From f039f7c367f182149c91a42e0869d333ea527d21 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Thu, 13 Jun 2013 06:06:29 +0000 Subject: [PATCH] Initial port of wxPython demo from Classic to Phoenix. Pulled and squashed from https://github.com/RobinD42/Phoenix/pull/7 Thanks Metallicow! git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@74199 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- demo/AUI_MDI.py | 2 +- demo/About.py | 2 +- demo/AboutBox.py | 10 +- demo/AdjustChannels.py | 53 +- demo/AlphaDrawing.py | 2 +- demo/AnimateCtrl.py | 12 +- demo/ArtProvider.py | 24 +- demo/BannerWindow.py | 1 + demo/BitmapButton.py | 12 +- demo/BitmapComboBox.py | 8 +- demo/BitmapFromBuffer.py | 17 +- demo/Button.py | 14 +- demo/Calendar.py | 10 +- demo/CalendarCtrl.py | 39 +- demo/CheckBox.py | 10 +- demo/CheckListCtrlMixin.py | 18 +- demo/Choice.py | 10 +- demo/ColorPanel.py | 2 +- demo/ColourDB.py | 22 +- demo/ColourDialog.py | 27 +- demo/ColourSelect.py | 4 +- demo/ComboBox.py | 14 +- demo/ComboCtrl.py | 396 ++----------- demo/CommandLinkButton.py | 3 +- demo/Cursor.py | 6 +- demo/CustomDragAndDrop.py | 36 +- demo/DVC_CustomRenderer.py | 2 +- demo/DVC_DataViewModel.py | 92 +-- demo/DVC_IndexListModel.py | 32 +- demo/DVC_ListCtrl.py | 8 +- demo/DVC_TreeCtrl.py | 10 +- demo/DatePickerCtrl.py | 27 +- demo/Dialog.py | 14 +- demo/DialogUnits.py | 2 +- demo/DragAndDrop.py | 4 +- demo/DragImage.py | 2 +- demo/DrawXXXList.py | 38 +- demo/EventManager.py | 17 +- demo/FileDialog.py | 22 +- demo/FileHistory.py | 17 +- demo/FindReplaceDialog.py | 2 +- demo/FloatBar.py | 26 +- demo/FloatCanvas.py | 3 +- demo/FontDialog.py | 14 +- demo/FontEnumerator.py | 4 +- demo/Frame.py | 16 +- demo/GLCanvas.py | 4 +- demo/Gauge.py | 6 +- demo/GenericButtons.py | 8 +- demo/GenericDirCtrl.py | 16 +- demo/GraphicsContext.py | 36 +- demo/GraphicsGradient.py | 15 +- demo/GridBagSizer.py | 6 +- demo/GridCustEditor.py | 14 +- demo/GridSimple.py | 2 +- demo/GridStdEdRend.py | 6 +- demo/Grid_MegaExample.py | 16 +- demo/HTML2_WebView.py | 4 +- demo/HtmlWindow.py | 8 +- demo/I18N.py | 74 +-- demo/Image.py | 4 +- demo/ImageFromStream.py | 2 +- demo/Img2PyArtProvider.py | 6 +- demo/ItemsPicker.py | 20 +- demo/Joystick.py | 89 ++- demo/KeyEvents.py | 38 +- demo/LayoutConstraints.py | 2 +- demo/ListBox.py | 16 +- demo/ListCtrl.py | 124 ++-- demo/ListCtrl_edit.py | 22 +- demo/ListCtrl_virtual.py | 23 +- demo/MDIDemo.py | 17 +- demo/MDISashDemo.py | 44 +- demo/MVCTree.py | 14 +- demo/Main.py | 554 +++++++++--------- demo/Mask.py | 8 +- demo/MaskedEditControls.py | 2 +- demo/MediaCtrl.py | 1 - demo/Menu.py | 63 ++- demo/MimeTypesManager.py | 44 +- demo/MiniFrame.py | 12 +- demo/MultiSash.py | 24 +- demo/Notebook.py | 6 +- demo/OwnerDrawnComboBox.py | 22 +- demo/PenAndBrushStyles.py | 30 +- demo/Pickers.py | 10 +- demo/PlateButton.py | 2 +- demo/PopupControl.py | 13 +- demo/PopupMenu.py | 8 +- demo/PrintDialog.py | 5 +- demo/PrintFramework.py | 45 +- demo/RawBitmapAccess.py | 14 +- demo/ResizeWidget.py | 13 +- demo/SashWindow.py | 55 +- demo/ScrolledWindow.py | 9 +- demo/ShapedWindow.py | 23 +- demo/Sizers.py | 34 +- demo/Slider.py | 10 +- demo/Sound.py | 18 +- demo/StatusBar.py | 24 +- demo/StyledTextCtrl_1.py | 85 ++- demo/StyledTextCtrl_2.py | 12 +- demo/SystemSettings.py | 23 +- demo/TablePrint.py | 30 +- demo/Ticker.py | 53 +- demo/TimeCtrl.py | 10 +- demo/ToolBar.py | 35 +- demo/TreeCtrl.py | 37 +- demo/UIActionSimulator.py | 6 +- demo/URLDragAndDrop.py | 5 +- demo/Unicode.py | 50 +- demo/Validator.py | 22 +- demo/WIPzChecklistPhoenixDemo.txt | 779 ++++++++++++++++++++++++++ demo/Wizard.py | 37 +- demo/XmlResource.py | 4 +- demo/agw/AUI.py | 44 +- demo/agw/AquaButton.py | 32 +- demo/agw/BalloonTip.py | 69 +-- demo/agw/ButtonPanel.py | 251 ++++----- demo/agw/FlatMenu.py | 162 +++--- demo/agw/FlatNotebook.py | 186 +++--- demo/agw/FloatSpin.py | 60 +- demo/agw/FoldPanelBar.py | 38 +- demo/agw/FourWaySplitter.py | 18 +- demo/agw/GradientButton.py | 18 +- demo/agw/LabelBook.py | 12 +- demo/agw/MacLargeDemo.py | 92 +-- demo/agw/PeakMeter.py | 26 +- demo/agw/PersistentControls.py | 74 +-- demo/agw/PieCtrl.py | 2 +- demo/agw/PyGauge.py | 40 +- demo/agw/PyProgress.py | 4 +- demo/agw/RibbonBar.py | 114 ++-- demo/agw/RulerCtrl.py | 28 +- demo/agw/ShapedButton.py | 156 +++--- demo/agw/ShortcutEditor.py | 2 +- demo/agw/SpeedMeter.py | 150 ++--- demo/agw/SuperToolTip.py | 56 +- demo/agw/ThumbnailCtrl.py | 106 ++-- demo/agw/ToasterBox.py | 4 +- demo/agw/UltimateListCtrl.py | 6 +- demo/agw/UltimateReportDemo.py | 198 +++---- demo/agw/UltimateVirtualDemo.py | 32 +- demo/agw/Windows7Explorer_Contents.py | 82 +-- demo/agw/XLSGrid.py | 4 +- demo/agw/ZoomBar.py | 42 +- demo/bitmaps/phoenix_title.png | Bin 0 -> 5702 bytes demo/bitmaps/phoenix_top.png | Bin 0 -> 90998 bytes demo/bitmaps/splash.png | Bin 64072 -> 95824 bytes demo/demo.pyw | 4 + demo/run.py | 14 +- demo/version.py | 2 +- 152 files changed, 3244 insertions(+), 2863 deletions(-) create mode 100644 demo/BannerWindow.py create mode 100644 demo/WIPzChecklistPhoenixDemo.txt create mode 100644 demo/bitmaps/phoenix_title.png create mode 100644 demo/bitmaps/phoenix_top.png create mode 100644 demo/demo.pyw diff --git a/demo/AUI_MDI.py b/demo/AUI_MDI.py index 50bbb6d3..6a42ff39 100644 --- a/demo/AUI_MDI.py +++ b/demo/AUI_MDI.py @@ -30,7 +30,7 @@ class ParentFrame(wx.aui.AuiMDIParentFrame): def OnNewChild(self, evt): self.count += 1 child = ChildFrame(self, self.count) - child.Activate() + child.Show() def OnDoClose(self, evt): # Close all ChildFrames first else Python crashes diff --git a/demo/About.py b/demo/About.py index c9ea6ed1..62eb7408 100644 --- a/demo/About.py +++ b/demo/About.py @@ -66,7 +66,7 @@ demo item so you can learn how to use the classes yourself.

if __name__ == '__main__': - app = wx.PySimpleApp() + app = wx.App() dlg = MyAboutBox(None) dlg.ShowModal() dlg.Destroy() diff --git a/demo/AboutBox.py b/demo/AboutBox.py index fdec097b..dc5f5790 100644 --- a/demo/AboutBox.py +++ b/demo/AboutBox.py @@ -1,5 +1,5 @@ - import wx +import wx.adv from wx.lib.wordwrap import wordwrap #---------------------------------------------------------------------- @@ -15,7 +15,7 @@ class TestPanel(wx.Panel): def OnButton(self, evt): # First we create and fill the info object - info = wx.AboutDialogInfo() + info = wx.adv.AboutDialogInfo() info.Name = "Hello World" info.Version = "1.2.3" info.Copyright = "(C) 2006 Programmers and Coders Everywhere" @@ -23,7 +23,7 @@ class TestPanel(wx.Panel): "A \"hello world\" program is a software program that prints out " "\"Hello world!\" on a display device. It is used in many introductory " "tutorials for teaching a programming language." - + "\n\nSuch a program is typically one of the simplest programs possible " "in a computer language. A \"hello world\" program can be a useful " "sanity test to make sure that a language's compiler, development " @@ -37,8 +37,8 @@ class TestPanel(wx.Panel): info.License = wordwrap(licenseText, 500, wx.ClientDC(self)) # Then we call wx.AboutBox giving it that info object - wx.AboutBox(info) - + wx.adv.AboutBox(info) + #---------------------------------------------------------------------- diff --git a/demo/AdjustChannels.py b/demo/AdjustChannels.py index 8d0a5bb9..9fc2a532 100644 --- a/demo/AdjustChannels.py +++ b/demo/AdjustChannels.py @@ -11,74 +11,73 @@ class TestAdjustChannels(wx.Panel): def __init__(self, parent, log): self.log = log wx.Panel.__init__(self, parent, -1) - + topsizer= wx.BoxSizer(wx.HORIZONTAL) # left controls, right image output - + # slider controls controls ctrlsizer= wx.BoxSizer(wx.VERTICAL) - + label= wx.StaticText(self, -1, "Factor red in %") label.SetForegroundColour("RED") ctrlsizer.Add(label, 0, wx.ALL, 5) sliderred= wx.Slider(self, wx.NewId(), 100, 0, 200, size=(150, -1), style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS) sliderred.SetForegroundColour("RED") - sliderred.SetTickFreq(50, 5) + sliderred.SetTickFreq(50) ctrlsizer.Add(sliderred) ctrlsizer.AddSpacer(15) - + label= wx.StaticText(self, -1, "Factor green in %") label.SetForegroundColour("GREEN") ctrlsizer.Add(label, 0, wx.ALL, 5) slidergreen= wx.Slider(self, wx.NewId(), 100, 0, 200, size=(150, -1), style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS) slidergreen.SetForegroundColour("GREEN") - slidergreen.SetTickFreq(50, 5) + slidergreen.SetTickFreq(50) ctrlsizer.Add(slidergreen) ctrlsizer.AddSpacer(15) - + label= wx.StaticText(self, -1, "Factor blue in %") label.SetForegroundColour("BLUE") ctrlsizer.Add(label, 0, wx.ALL, 5) sliderblue= wx.Slider(self, wx.NewId(), 100, 0, 200, size=(150, -1), style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS) sliderblue.SetForegroundColour("BLUE") - sliderblue.SetTickFreq(50, 5) + sliderblue.SetTickFreq(50) ctrlsizer.Add(sliderblue) ctrlsizer.AddSpacer(20) - + label= wx.StaticText(self, -1, "Factor alpha in %") ctrlsizer.Add(label, 0, wx.ALL, 5) slideralpha= wx.Slider(self, wx.NewId(), 100, 0, 200, size=(150, -1), style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS) - slideralpha.SetTickFreq(50, 1) + slideralpha.SetTickFreq(50) ctrlsizer.Add(slideralpha) - + topsizer.Add(ctrlsizer, 0, wx.ALL, 10) - + # image window self.images= ImageWindow(self) topsizer.Add(self.images, 1, wx.EXPAND) - + self.SetSizer(topsizer) topsizer.Layout() - + # forward the slider change events to the image window sliderred.Bind(wx.EVT_SCROLL, self.images.OnScrollRed) slidergreen.Bind(wx.EVT_SCROLL, self.images.OnScrollGreen) sliderblue.Bind(wx.EVT_SCROLL, self.images.OnScrollBlue) slideralpha.Bind(wx.EVT_SCROLL, self.images.OnScrollAlpha) - - + class ImageWindow(wx.Window): def __init__(self, parent): wx.Window.__init__(self, parent) self.image1= wx.Image(opj('bitmaps/image.bmp'), wx.BITMAP_TYPE_BMP) self.image2= wx.Image(opj('bitmaps/toucan.png'), wx.BITMAP_TYPE_PNG) - + # the factors -- 1.0 does not not modify the image self.factorred= 1.0 self.factorgreen= 1.0 self.factorblue= 1.0 self.factoralpha= 1.0 - + self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) self.Bind(wx.EVT_SIZE, self.OnSize) @@ -106,30 +105,30 @@ class ImageWindow(wx.Window): def OnPaint(self, event): dc= wx.PaintDC(self) dc= wx.BufferedDC(dc) - + # paint a background to show the alpha manipulation dc.SetBackground(wx.Brush("WHITE")) dc.Clear() dc.SetBrush(wx.Brush("GREY", wx.CROSSDIAG_HATCH)) - windowsize= self.GetSizeTuple() + windowsize= self.GetSize() dc.DrawRectangle(0, 0, windowsize[0], windowsize[1]) - + # apply correction to the image channels via wx.Image.AdjustChannels image= self.image1.AdjustChannels(self.factorred, self.factorgreen, self.factorblue, self.factoralpha) - bitmap= wx.BitmapFromImage(image) + bitmap= wx.Bitmap(image) dc.DrawBitmap(bitmap, 10, 10, True) image= self.image2.AdjustChannels(self.factorred, self.factorgreen, self.factorblue, self.factoralpha) - bitmap= wx.BitmapFromImage(image) + bitmap= wx.Bitmap(image) dc.DrawBitmap(bitmap, 10, 110, True) def OnSize(self, event): self.Refresh() - - def OnEraseBackground(self, event): - pass - + def OnEraseBackground(self, event): + pass + + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/AlphaDrawing.py b/demo/AlphaDrawing.py index 6fb15a97..9649d0a7 100644 --- a/demo/AlphaDrawing.py +++ b/demo/AlphaDrawing.py @@ -34,7 +34,7 @@ then these squares should be transparent. dc.SetPen(wx.Pen(penclr)) dc.SetBrush(wx.Brush(brushclr)) rect.SetPosition(pos) - dc.DrawRoundedRectangleRect(rect, 8) + dc.DrawRoundedRectangle(rect, 8) # some additional testing stuff #dc.SetPen(wx.Pen(wx.Colour(0,0,255, 196))) diff --git a/demo/AnimateCtrl.py b/demo/AnimateCtrl.py index d4a2db95..29cb4dbe 100644 --- a/demo/AnimateCtrl.py +++ b/demo/AnimateCtrl.py @@ -1,6 +1,6 @@ import wx -import wx.animate +from wx.adv import Animation, AnimationCtrl from Main import opj GIFNames = [ @@ -21,14 +21,14 @@ class TestPanel(wx.Panel): sizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) for name in GIFNames: - ani = wx.animate.Animation(opj(name)) - ctrl = wx.animate.AnimationCtrl(self, -1, ani) - ctrl.SetUseWindowBackgroundColour() + ani = Animation(opj(name)) + ctrl = AnimationCtrl(self, -1, ani) + ctrl.SetBackgroundColour(self.GetBackgroundColour()) ctrl.Play() - sizer.AddF(ctrl, wx.SizerFlags().Border(wx.ALL, 10)) + sizer.Add(ctrl, 0, wx.ALL, 10) border = wx.BoxSizer() - border.AddF(sizer, wx.SizerFlags(1).Expand().Border(wx.ALL, 20)) + border.Add(sizer, 1, wx.EXPAND | wx.ALL, 20) self.SetSizer(border) diff --git a/demo/ArtProvider.py b/demo/ArtProvider.py index 774fdf1b..b9c6c344 100644 --- a/demo/ArtProvider.py +++ b/demo/ArtProvider.py @@ -107,7 +107,7 @@ class MyArtProvider(wx.ArtProvider): elif artid == wx.ART_TICK_MARK: bmp = makeBitmap(tick_png) - if bmp.Ok(): + if bmp.IsOk(): self.log.write("MyArtProvider: providing %s:%s at %s\n" %(artid, client, size)) return bmp @@ -150,7 +150,7 @@ class TestPanel(wx.Panel): fgs.Add((10, 10), 0, wx.ALIGN_CENTRE|wx.ALL, 5) box = wx.BoxSizer(wx.VERTICAL) - bmp = wx.EmptyBitmap(16,16) + bmp = wx.Bitmap(16,16) self.bmp16 = wx.StaticBitmap(self, -1, bmp) box.Add(self.bmp16, 0, wx.ALIGN_CENTRE|wx.ALL, 5) text = wx.StaticText(self, -1, "16x16") @@ -159,7 +159,7 @@ class TestPanel(wx.Panel): fgs.Add(box, 0, wx.ALIGN_CENTRE|wx.ALL, 5) box = wx.BoxSizer(wx.VERTICAL) - bmp = wx.EmptyBitmap(32,32) + bmp = wx.Bitmap(32,32) self.bmp32 = wx.StaticBitmap(self, -1, bmp) box.Add(self.bmp32, 0, wx.ALIGN_CENTRE|wx.ALL, 5) text = wx.StaticText(self, -1, "32x32") @@ -168,7 +168,7 @@ class TestPanel(wx.Panel): fgs.Add(box, 0, wx.ALIGN_CENTRE|wx.ALL, 5) box = wx.BoxSizer(wx.VERTICAL) - bmp = wx.EmptyBitmap(48,48) + bmp = wx.Bitmap(48,48) self.bmp48 = wx.StaticBitmap(self, -1, bmp) box.Add(self.bmp48, 0, wx.ALIGN_CENTRE|wx.ALL, 5) text = wx.StaticText(self, -1, "48x48") @@ -210,24 +210,24 @@ class TestPanel(wx.Panel): bmp = wx.ArtProvider.GetBitmap(self.artid, self.client, (16,16)) - if not bmp.Ok(): - bmp = wx.EmptyBitmap(16,16) + if not bmp.IsOk(): + bmp = wx.Bitmap(16,16) self.clearBmp(bmp) self.bmp16.SetBitmap(bmp) bmp = wx.ArtProvider.GetBitmap(self.artid, self.client, (32,32)) - if not bmp.Ok(): - bmp = wx.EmptyBitmap(32,32) + if not bmp.IsOk(): + bmp = wx.Bitmap(32,32) self.clearBmp(bmp) self.bmp32.SetBitmap(bmp) bmp = wx.ArtProvider.GetBitmap(self.artid, self.client, (48,48)) - if not bmp.Ok(): - bmp = wx.EmptyBitmap(48,48) + if not bmp.IsOk(): + bmp = wx.Bitmap(48,48) self.clearBmp(bmp) self.bmp48.SetBitmap(bmp) @@ -238,7 +238,7 @@ class TestPanel(wx.Panel): dc.SelectObject(bmp) dc.SetBackground(wx.Brush("white")) dc.Clear() - + #---------------------------------------------------------------------- @@ -276,7 +276,7 @@ provided by wx.ArtProvider.GetBitmap or wx.ArtProvider.GetIcon methods. def makeBitmap(data): stream = cStringIO.StringIO(data) - return wx.BitmapFromImage(wx.ImageFromStream(stream)) + return wx.Bitmap(wx.Image(stream)) back_png = \ diff --git a/demo/BannerWindow.py b/demo/BannerWindow.py new file mode 100644 index 00000000..8fae2738 --- /dev/null +++ b/demo/BannerWindow.py @@ -0,0 +1 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- import wx import wx.adv phoenix = ("A phoenix is a mythical bird with a colorful plumage and a tail of gold and scarlet \n" "(or purple and blue, according to some sources). It has a 500 to 1,000 year life-cycle, \n" "near the end of which it builds itself a nest of myrrh twigs that then ignites; both nest \n" "and bird burn fiercely and are reduced to ashes, from which a new, young phoenix or phoenix \n" "egg arises, reborn anew to live again. The new phoenix is destined to live as long as its old \n" "self. In some stories, the new phoenix embalms the ashes of its old self in an egg made of myrrh \n" "and deposits it in the Egyptian city of Heliopolis (sun city in Greek). The bird was also said to \n" "regenerate when hurt or wounded by a foe, thus being immortal and invincible - it is also said that \n" "it can heal a person with a tear from its eyes and make them temporarily immune to death. \n" "The Phoenix is a symbol of fire and divinity. ") class MyBannerWindowFrame(wx.Frame): def __init__(self, parent, id, title): # ... create the frame itself ... wx.Frame.__init__(self, parent, id, title) # Set background Colour. This will become the black border self.SetBackgroundColour(wx.BLACK) pnxBmp = wx.Bitmap('bitmaps/phoenix_top.png') bmpsz = pnxBmp.GetSize() # Create and initialize the banner. whitePanel = wx.Panel(self, -1, size=(-1, bmpsz[1])) whitePanel.SetBackgroundColour(wx.WHITE) # Create and initialize the 1st banner and define a bitmap. banner1 = wx.adv.BannerWindow(whitePanel, dir=wx.BOTTOM) banner1.SetBitmap(pnxBmp) whiteSizer = wx.BoxSizer(wx.HORIZONTAL) whiteSizer.Add(banner1, 1) whitePanel.SetSizer(whiteSizer) # Create and initialize the 2nd banner and define the gradient text. banner2 = wx.adv.BannerWindow(self, dir=wx.TOP) banner2.SetGradient(start='#FF8000', end='#FFFFFF') banner2.SetText(phoenix, "") # Layout vsizer = wx.BoxSizer(wx.VERTICAL) vsizer.Add(whitePanel, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5) vsizer.Add(banner2, 1, wx.BOTTOM | wx.LEFT | wx.RIGHT, 5) self.SetSizer(vsizer) class TestPanel(wx.Panel): def __init__(self, parent, log): self.log = log wx.Panel.__init__(self, parent, -1) b = wx.Button(self, -1, "Create and Show a BannerWindow", (50,50)) self.Bind(wx.EVT_BUTTON, self.OnButton, b) def OnButton(self, evt): win = MyBannerWindowFrame(self, -1, "This is a BannerWindow") win.SetSize((700, 350)) win.CenterOnParent(wx.BOTH) win.Show(True) def runTest(frame, nb, log): win = TestPanel(nb, log) return win #--------------------------------------------------------------------------- overview = """\ A simple banner window showing either a bitmap or text. Banner windows can be used to present some overview of the current window contents to the user in an aesthetically pleasant way. They are typically positioned along the left or top edge of the window (although this class also supports right-aligned and bottom-aligned banners) and show either a bitmap with a logo or a few lines of text on a gradient-filled background. """ if __name__ == '__main__': app = wx.App() win = MyBannerWindowFrame(None, -1, "This is a BannerWindow") win.SetSize((700, 350)) win.CenterOnParent(wx.BOTH) win.Show(True) app.MainLoop() \ No newline at end of file diff --git a/demo/BitmapButton.py b/demo/BitmapButton.py index 0bd5ed03..a3ae3d94 100644 --- a/demo/BitmapButton.py +++ b/demo/BitmapButton.py @@ -34,22 +34,22 @@ class TestPanel(wx.Panel): bmp.SetMask(mask) b = wx.BitmapButton(self, -1, bmp, (20, 20), (bmp.GetWidth()+10, bmp.GetHeight()+10)) - b.SetToolTipString("This is a bitmap button.") + b.SetToolTip("This is a bitmap button.") self.Bind(wx.EVT_BUTTON, self.OnClick, b) b = wx.BitmapButton(self, -1, bmp, (20, 120), style = wx.NO_BORDER) - + # hide a little surprise in the button... img = images.Robin.GetImage() # we need to make it be the same size as the primary image, so # grab a subsection of this new image cropped = img.GetSubImage((20, 20, bmp.GetWidth(), bmp.GetHeight())) - b.SetBitmapSelected(cropped.ConvertToBitmap()) + b.SetBitmapPressed(cropped.ConvertToBitmap()) - b.SetToolTipString("This is a bitmap button with \nwx.NO_BORDER style.") + b.SetToolTip("This is a bitmap button with \nwx.NO_BORDER style.") self.Bind(wx.EVT_BUTTON, self.OnClick, b) - + def OnClick(self, event): self.log.write("Click! (%d)\n" % event.GetId()) @@ -69,7 +69,7 @@ overview = """

A BitmapButton control displays a bitmap. It can have a separate bitmap for each button state: normal, selected, disabled.

-

The bitmaps to be displayed should have a small number of colours, such as 16, +

The bitmaps to be displayed should have a small number of colours, such as 16, to avoid palette problems.

A bitmap can be derived from most image formats using the wx.Image class.

diff --git a/demo/BitmapComboBox.py b/demo/BitmapComboBox.py index 30d9f549..8a15d2c2 100644 --- a/demo/BitmapComboBox.py +++ b/demo/BitmapComboBox.py @@ -1,6 +1,6 @@ import wx -import wx.combo +import wx.adv import images @@ -11,8 +11,8 @@ class TestPanel(wx.Panel): self.log = log wx.Panel.__init__(self, parent, -1) - bcb1 = wx.combo.BitmapComboBox(self, pos=(25,25), size=(200,-1)) - bcb2 = wx.combo.BitmapComboBox(self, pos=(250,25), size=(200,-1)) + bcb1 = wx.adv.BitmapComboBox(self, pos=(25,25), size=(200,-1)) + bcb2 = wx.adv.BitmapComboBox(self, pos=(250,25), size=(200,-1)) for bcb in [bcb1, bcb2]: for x in range(12): @@ -32,7 +32,7 @@ class TestPanel(wx.Panel): cd = bcb.GetClientData(idx) self.log.write("EVT_COMBOBOX: Id %d, string '%s', clientData '%s'" % (idx, st, cd)) - + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/BitmapFromBuffer.py b/demo/BitmapFromBuffer.py index 69f2c066..15345b75 100644 --- a/demo/BitmapFromBuffer.py +++ b/demo/BitmapFromBuffer.py @@ -10,7 +10,7 @@ class TestPanel(wx.Panel): wx.Panel.__init__(self, parent, -1) self.Bind(wx.EVT_PAINT, self.OnPaint) self.width, self.height = 120,120 - + self.MakeBitmapRGB(self.width, self.height) self.MakeBitmapRGBA(self.width, self.height) self.MakeBitmapRGBpA(self.width, self.height) @@ -28,7 +28,6 @@ class TestPanel(wx.Panel): else: return r, g, b - def MakeBitmapRGB(self, width, height): # Make a bitmap using an array of RGB bytes bpp = 3 # bytes per pixel @@ -42,9 +41,7 @@ class TestPanel(wx.Panel): bytes[offset + 1] = g bytes[offset + 2] = b - self.rgbBmp = wx.BitmapFromBuffer(width, height, bytes) - - + self.rgbBmp = wx.Bitmap().FromBuffer(width, height, bytes) def MakeBitmapRGBA(self, width, height): # Make a bitmap using an array of RGBA bytes @@ -60,8 +57,7 @@ class TestPanel(wx.Panel): bytes[offset + 2] = b bytes[offset + 3] = a - self.rgbaBmp = wx.BitmapFromBufferRGBA(width, height, bytes) - + self.rgbaBmp = wx.Bitmap().FromBufferRGBA(width, height, bytes) def MakeBitmapRGBpA(self, width, height): # Make a bitmap using an array of RGB bytes plus a separate @@ -81,8 +77,7 @@ class TestPanel(wx.Panel): # pixels for this example, it could just as easily have # varying alpha values like the other sample. alpha = array.array('B', [128]*width*height) - self.rgbaBmp2 = wx.BitmapFromBuffer(width, height, bytes, alpha) - + self.rgbaBmp2 = wx.Bitmap().FromBufferAndAlpha(width, height, bytes, alpha) def DrawBitmapAndMessage(self, dc, bmp, msg, x_, y_): x, y = x_, y_ @@ -96,7 +91,6 @@ class TestPanel(wx.Panel): # draw the bitmap over the text dc.DrawBitmap(bmp, x+15,y_+15, True) - def OnPaint(self, evt): dc = wx.PaintDC(self) self.DrawBitmapAndMessage(dc, self.rgbBmp, "No alpha channel in this image", 30,35) @@ -104,9 +98,6 @@ class TestPanel(wx.Panel): self.DrawBitmapAndMessage(dc, self.rgbaBmp2,"This one made with RGB+A", 180,220) - - - #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/Button.py b/demo/Button.py index 9493ae2d..bde3f382 100644 --- a/demo/Button.py +++ b/demo/Button.py @@ -15,17 +15,17 @@ class TestPanel(wx.Panel): b.SetDefault() b.SetSize(b.GetBestSize()) - b = wx.Button(self, 20, "HELLO AGAIN!", (20, 80)) + b = wx.Button(self, 20, "HELLO AGAIN!", (20, 80)) self.Bind(wx.EVT_BUTTON, self.OnClick, b) - b.SetToolTipString("This is a Hello button...") + b.SetToolTip("This is a Hello button...") b = wx.Button(self, 40, "Flat Button?", (20,160), style=wx.NO_BORDER) - b.SetToolTipString("This button has a style flag of wx.NO_BORDER.\n" + b.SetToolTip("This button has a style flag of wx.NO_BORDER.\n" "On some platforms that will give it a flattened look.") self.Bind(wx.EVT_BUTTON, self.OnClick, b) b = wx.Button(self, 50, "wx.Button with icon", (20, 220)) - b.SetToolTipString("wx.Button can how have an icon on the left, right,\n" + b.SetToolTip("wx.Button can how have an icon on the left, right,\n" "above or below the label.") self.Bind(wx.EVT_BUTTON, self.OnClick, b) @@ -36,16 +36,16 @@ class TestPanel(wx.Panel): #wx.BOTTOM ) b.SetBitmapMargins((2,2)) # default is 4 but that seems too big to me. - + # Setting the bitmap and margins changes the best size, so # reset the initial size since we're not using a sizer in this # example which would have taken care of this for us. - b.SetInitialSize() + b.SetInitialSize() #b = wx.Button(self, 60, "Multi-line\nbutton", (20, 280)) #b = wx.Button(self, 70, pos=(160, 280)) #b.SetLabel("Another\nmulti-line") - + def OnClick(self, event): self.log.write("Click! (%d)\n" % event.GetId()) diff --git a/demo/Calendar.py b/demo/Calendar.py index 562844f4..224e8270 100644 --- a/demo/Calendar.py +++ b/demo/Calendar.py @@ -16,7 +16,7 @@ # # o Ugh. AFter updating to the Bind() method, things lock up # on various control clicks. Will have to debug. Only seems -# to happen on windows with calendar controls, though. +# to happen on windows with calendar controls, though. # # 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net) # @@ -27,7 +27,7 @@ import os import wx -import wx.lib.calendar +import wx.lib.calendar import images @@ -637,13 +637,13 @@ def runTest(frame, nb, log): overview = """\ -This control provides a Calendar control class for displaying and selecting dates. +This control provides a Calendar control class for displaying and selecting dates. In addition, the class is extended and can be used for printing/previewing. -Additional features include weekend highlighting and business type Monday-Sunday +Additional features include weekend highlighting and business type Monday-Sunday format. -See example for various methods used to set display month, year, and highlighted +See example for various methods used to set display month, year, and highlighted dates (different font and background colours). by Lorne White diff --git a/demo/CalendarCtrl.py b/demo/CalendarCtrl.py index f7902fec..d592a62a 100644 --- a/demo/CalendarCtrl.py +++ b/demo/CalendarCtrl.py @@ -1,6 +1,7 @@ -import wx -import wx.calendar as wxcal +import wx +import wx.adv +from wx.adv import CalendarCtrl #---------------------------------------------------------------------- @@ -20,19 +21,19 @@ class TestPanel(wx.Panel): wx.Panel.__init__(self, parent, ID) self.log = log - native = wxcal.CalendarCtrl(self, -1, wx.DateTime.Today(), - style=wxcal.CAL_SEQUENTIAL_MONTH_SELECTION) + native = self.cal = CalendarCtrl(self, -1, wx.DateTime().Today(), + style=wx.adv.CAL_SEQUENTIAL_MONTH_SELECTION) txt = wx.StaticText(self, -1, description) txt.Wrap(300) - cal = self.cal = wxcal.GenericCalendarCtrl(self, -1, wx.DateTime.Today(), - style = wxcal.CAL_SHOW_HOLIDAYS - | wxcal.CAL_SUNDAY_FIRST - | wxcal.CAL_SEQUENTIAL_MONTH_SELECTION - ) + # cal = self.cal = GenericCalendarCtrl(self, -1, wx.DateTime().Today(), + # style = wx.adv.CAL_SHOW_HOLIDAYS + # | wx.adv.CAL_SUNDAY_FIRST + # | wx.adv.CAL_SEQUENTIAL_MONTH_SELECTION + # ) - cal2 = wxcal.GenericCalendarCtrl(self, -1, wx.DateTime.Today()) + # cal2 = wxcal.GenericCalendarCtrl(self, -1, wx.DateTime().Today()) # Track a few holidays @@ -41,22 +42,22 @@ class TestPanel(wx.Panel): # bind some event handlers to each calendar - for c in native, cal, cal2: - c.Bind(wxcal.EVT_CALENDAR, self.OnCalSelected) - c.Bind(wxcal.EVT_CALENDAR_MONTH, self.OnChangeMonth) - c.Bind(wxcal.EVT_CALENDAR_SEL_CHANGED, self.OnCalSelChanged) - c.Bind(wxcal.EVT_CALENDAR_WEEKDAY_CLICKED, self.OnCalWeekdayClicked) + for c in [native]:#, cal, cal2 + c.Bind(wx.adv.EVT_CALENDAR, self.OnCalSelected) + ## c.Bind(wx.adv.EVT_CALENDAR_MONTH, self.OnChangeMonth) + c.Bind(wx.adv.EVT_CALENDAR_SEL_CHANGED, self.OnCalSelChanged) + c.Bind(wx.adv.EVT_CALENDAR_WEEKDAY_CLICKED, self.OnCalWeekdayClicked) # create some sizers for layout fgs = wx.FlexGridSizer(cols=2, hgap=50, vgap=50) fgs.Add(native) fgs.Add(txt) - fgs.Add(cal) - fgs.Add(cal2) + # fgs.Add(cal) + # fgs.Add(cal2) box = wx.BoxSizer() box.Add(fgs, 1, wx.EXPAND|wx.ALL, 25) self.SetSizer(box) - + def OnCalSelected(self, evt): self.log.write('OnCalSelected: %s\n' % evt.GetDate()) @@ -84,7 +85,7 @@ class TestPanel(wx.Panel): # August 14th is a special day, mark it with a blue square... if cur_month == 8: - attr = wxcal.CalendarDateAttr(border=wxcal.CAL_BORDER_SQUARE, + attr = wxcal.CalendarDateAttr(border=wx.adv.CAL_BORDER_SQUARE, colBorder="blue") cal.SetAttr(14, attr) else: diff --git a/demo/CheckBox.py b/demo/CheckBox.py index c54edafe..0bc5b45d 100644 --- a/demo/CheckBox.py +++ b/demo/CheckBox.py @@ -14,11 +14,11 @@ class TestCheckBox(wx.Panel): cb2 = wx.CheckBox(self, -1, "Oranges")#, (65, 60), (150, 20), wx.NO_BORDER) cb2.SetValue(True) cb3 = wx.CheckBox(self, -1, "Pears")#, (65, 80), (150, 20), wx.NO_BORDER) - + cb4 = wx.CheckBox(self, -1, "3-state checkbox", style=wx.CHK_3STATE|wx.CHK_ALLOW_3RD_STATE_FOR_USER) cb5 = wx.CheckBox(self, -1, "Align Right", style=wx.ALIGN_RIGHT) - + self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, cb1) self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, cb2) @@ -40,14 +40,14 @@ class TestCheckBox(wx.Panel): border.Add(st, 0, wx.ALL, 15) border.Add(sizer, 0, wx.LEFT, 50) self.SetSizer(border) - + def EvtCheckBox(self, event): self.log.write('EvtCheckBox: %d\n' % event.IsChecked()) cb = event.GetEventObject() if cb.Is3State(): self.log.write("\t3StateValue: %s\n" % cb.Get3StateValue()) - + #--------------------------------------------------------------------------- @@ -59,7 +59,7 @@ def runTest(frame, nb, log): overview = """\ -A checkbox is a labelled box which is either on (checkmark is visible) or off +A checkbox is a labelled box which is either on (checkmark is visible) or off (no checkmark). """ diff --git a/demo/CheckListCtrlMixin.py b/demo/CheckListCtrlMixin.py index 0742b146..448aa2a2 100644 --- a/demo/CheckListCtrlMixin.py +++ b/demo/CheckListCtrlMixin.py @@ -15,7 +15,7 @@ class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin): def OnItemActivated(self, evt): - self.ToggleItem(evt.m_itemIndex) + self.ToggleItem(evt.Index) # this is called by the base class when an item is checked/unchecked @@ -46,10 +46,10 @@ class TestPanel(wx.Panel): for key, data in musicdata.iteritems(): index = self.list.InsertStringItem(sys.maxint, data[0]) - self.list.SetStringItem(index, 1, data[1]) - self.list.SetStringItem(index, 2, data[2]) + self.list.SetItem(index, 1, data[1]) + self.list.SetItem(index, 2, data[2]) self.list.SetItemData(index, key) - + self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE) self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE) self.list.SetColumnWidth(2, 100) @@ -60,13 +60,13 @@ class TestPanel(wx.Panel): self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self.list) - + def OnItemSelected(self, evt): - self.log.write('item selected: %s\n' % evt.m_itemIndex) - + self.log.write('item selected: %s\n' % evt.Index) + def OnItemDeselected(self, evt): - self.log.write('item deselected: %s\n' % evt.m_itemIndex) - + self.log.write('item deselected: %s\n' % evt.Index) + #---------------------------------------------------------------------- diff --git a/demo/Choice.py b/demo/Choice.py index ef9db235..15eccacb 100644 --- a/demo/Choice.py +++ b/demo/Choice.py @@ -20,7 +20,7 @@ class TestChoice(wx.Panel): def EvtChoice(self, event): self.log.WriteText('EvtChoice: %s\n' % event.GetString()) self.ch.Append("A new item") - + if event.GetString() == 'one': self.log.WriteText('Well done!\n') @@ -34,15 +34,15 @@ def runTest(frame, nb, log): #--------------------------------------------------------------------------- overview = """ -A Choice control is used to select one of a list of strings. Unlike a listbox, -only the current selection is visible until the user pulls down the menu of +A Choice control is used to select one of a list of strings. Unlike a listbox, +only the current selection is visible until the user pulls down the menu of choices. This demo illustrates how to set up the Choice control and how to extract the -selected choice once it is selected. +selected choice once it is selected. Note that the syntax of the constructor is different than the C++ implementation. -The number of choices and the choice array are consilidated into one python +The number of choices and the choice array are consilidated into one python list. """ diff --git a/demo/ColorPanel.py b/demo/ColorPanel.py index 29ef92c1..6c916e2c 100644 --- a/demo/ColorPanel.py +++ b/demo/ColorPanel.py @@ -1,5 +1,5 @@ # -# Note: this module is not a demo per se, but is used by many of +# Note: this module is not a demo per se, but is used by many of # the demo modules for various purposes. # diff --git a/demo/ColourDB.py b/demo/ColourDB.py index 4cce7599..b297e9b9 100644 --- a/demo/ColourDB.py +++ b/demo/ColourDB.py @@ -28,10 +28,10 @@ class TestWindow(wx.ScrolledWindow): # Using GetFullTextExtent(), we calculate a basic 'building block' # that will be used to draw a depiction of the color list. We're - # using 'Wy' as the model becuase 'W' is a wide character and 'y' + # using 'Wy' as the model becuase 'W' is a wide character and 'y' # has a descender. This constitutes a 'worst case' scenario, which means # that no matter what we draw later, text-wise, we'll have room for it - w,h,d,e = dc.GetFullTextExtent("Wy") + w,h,d,e = dc.GetFullTextExtent("Wy") # Height plus descender self.textHeight = h + d @@ -44,12 +44,12 @@ class TestWindow(wx.ScrolledWindow): # jmg 11/8/03: why 24? numCells = 24 - + # 'prep' our scroll bars. self.SetScrollbars( self.cellWidth, self.lineHeight, numCells, len(self.clrList) + 2 ) - + # Bind event handlers self.SetBackgroundStyle(wx.BG_STYLE_ERASE) self.Bind(wx.EVT_PAINT, self.OnPaint) @@ -103,7 +103,7 @@ class TestWindow(wx.ScrolledWindow): numColours = len(colours) if rgn: - # determine the subset of the color list that has been exposed + # determine the subset of the color list that has been exposed # and needs drawn. This is based on all the precalculation we # did in __init__() rect = rgn.GetBox() @@ -125,14 +125,14 @@ class TestWindow(wx.ScrolledWindow): dc.SetBrush(brush) dc.DrawRectangle(10 * self.cellWidth, y, 6 * self.cellWidth, self.textHeight) - + dc.DrawText(str(tuple(colours[line][1:])), 18 * self.cellWidth, y) hexstr = "#%02X%02X%02X" % tuple(colours[line][1:]) dc.DrawText(hexstr, 25 * self.cellWidth, y) - + # On wxGTK there needs to be a panel under wx.ScrolledWindows if they are # going to be in a wxNotebook. And, in this demo, we are. class TestPanel(wx.Panel): @@ -170,9 +170,9 @@ overview = """ ColourDB -

wxWindows maintains a database of standard RGB colours for a predefined -set of named colours (such as "BLACK'', "LIGHT GREY''). The application -may add to this set if desired by using Append. There is only one instance +

wxWindows maintains a database of standard RGB colours for a predefined +set of named colours (such as "BLACK'', "LIGHT GREY''). The application +may add to this set if desired by using Append. There is only one instance of this class: TheColourDatabase.

The colourdb library is a lightweight API that pre-defines @@ -188,7 +188,7 @@ font data to generate a "building block" type of construct for repetitive use.

With implementation of V2.5 and later, it is required to have a wx.App already -initialized before wx.updateColourDB() can be called. +initialized before wx.updateColourDB() can be called. Trying to do otherwise will cause an exception to be raised. diff --git a/demo/ColourDialog.py b/demo/ColourDialog.py index 13422421..74678b80 100644 --- a/demo/ColourDialog.py +++ b/demo/ColourDialog.py @@ -1,5 +1,5 @@ - -import wx + +import wx #--------------------------------------------------------------------------- @@ -15,7 +15,7 @@ class TestPanel(wx.Panel): def OnButton(self, evt): dlg = wx.ColourDialog(self) - # Ensure the full colour dialog is displayed, + # Ensure the full colour dialog is displayed, # not the abbreviated version. dlg.GetColourData().SetChooseFull(True) @@ -27,7 +27,10 @@ class TestPanel(wx.Panel): # ... then do something with it. The actual colour data will be # returned as a three-tuple (r, g, b) in this particular case. - self.log.WriteText('You selected: %s\n' % str(data.GetColour().Get())) + color = data.GetColour().Get() + self.log.WriteText('You selected: %s\n' % str(color)) + self.SetBackgroundColour(color) + self.Refresh() # Once the dialog is destroyed, Mr. wx.ColourData is no longer your # friend. Don't use it again! @@ -47,21 +50,21 @@ def runTest(frame, nb, log): overview = """\ This class represents the colour chooser dialog. -Use of this dialog is a multi-stage process. +Use of this dialog is a multi-stage process. -The actual information about how to display the dialog and the colors in the -dialog's 'registers' are contained in a wx.ColourData instance that is created by -the dialog at init time. Before displaying the dialog, you may alter these settings -to suit your needs. In the example, we set the dialog up to show the extended colour -data selection pane. Otherwise, only the more compact and less extensive colour -dialog is shown. You may also preset the colour as well as other items. +The actual information about how to display the dialog and the colors in the +dialog's 'registers' are contained in a wx.ColourData instance that is created by +the dialog at init time. Before displaying the dialog, you may alter these settings +to suit your needs. In the example, we set the dialog up to show the extended colour +data selection pane. Otherwise, only the more compact and less extensive colour +dialog is shown. You may also preset the colour as well as other items. If the user selects something and selects OK, then the wx.ColourData instance contains the colour data that the user selected. Before destroying the dialog, retrieve the data. Do not try to retain the wx.ColourData instance. It will probably not be valid after the dialog is destroyed. -Along with he wx.ColourDialog documentation, see also the wx.ColourData documentation +Along with he wx.ColourDialog documentation, see also the wx.ColourData documentation for details. """ diff --git a/demo/ColourSelect.py b/demo/ColourSelect.py index d255708d..f3aa1aaa 100644 --- a/demo/ColourSelect.py +++ b/demo/ColourSelect.py @@ -15,7 +15,7 @@ # - use sizers # - other minor "improvements" #---------------------------------------------------------------------------- -# +# import wx import wx.lib.colourselect as csel @@ -44,7 +44,7 @@ class TestColourSelect(wx.Panel): self.colourDefaults = csel.ColourSelect(self, -1) self.Bind(csel.EVT_COLOURSELECT, self.OnSelectColour, id=self.colourDefaults.GetId()) - + buttonSizer.AddMany([ (wx.StaticText(self, -1, "Default Colour/Size"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL), (self.colourDefaults, 0, wx.ALL, 3), diff --git a/demo/ComboBox.py b/demo/ComboBox.py index c4d6623c..cdf9b1c1 100644 --- a/demo/ComboBox.py +++ b/demo/ComboBox.py @@ -5,11 +5,11 @@ import wx class TestComboBox(wx.Panel): def OnSetFocus(self, evt): - print "OnSetFocus" + # print("OnSetFocus") evt.Skip() def OnKillFocus(self, evt): - print "OnKillFocus" + # print("OnKillFocus") evt.Skip() def __init__(self, parent, log): @@ -24,7 +24,7 @@ class TestComboBox(wx.Panel): wx.StaticText(self, -1, "Select one:", (15, 50), (75, 18)) # This combobox is created with a preset list of values. - cb = wx.ComboBox(self, 500, "default value", (90, 50), + cb = wx.ComboBox(self, 500, "default value", (90, 50), (160, -1), sampleList, wx.CB_DROPDOWN #| wx.TE_PROCESS_ENTER @@ -80,13 +80,13 @@ def runTest(frame, nb, log): overview = """\ -A ComboBox is like a combination of an edit control and a listbox. It can be -displayed as static list with editable or read-only text field; or a drop-down +A ComboBox is like a combination of an edit control and a listbox. It can be +displayed as static list with editable or read-only text field; or a drop-down list with text field; or a drop-down list without a text field. This example shows both a preset ComboBox and one that is dynamically created -(that is, it is initially empty but then we 'grow' it out of program-supplied -data). The former is common for read-only controls. +(that is, it is initially empty but then we 'grow' it out of program-supplied +data). The former is common for read-only controls. This example also shows the two form factors for the ComboBox. The first is more common, and resembles a Choice control. The latter, although less common, shows diff --git a/demo/ComboCtrl.py b/demo/ComboCtrl.py index eb2de5a1..02ec6a8f 100644 --- a/demo/ComboCtrl.py +++ b/demo/ComboCtrl.py @@ -1,49 +1,27 @@ import wx -import wx.combo + import os #---------------------------------------------------------------------- -class NullLog: - def write(*args): - pass +#---------------------------------------------------------------------- +# This class is used to provide an interface between a ComboCtrl and the +# ListCtrl that is used as the popoup for the combo widget. +class ListCtrlComboPopup(wx.ComboPopup): -# This class is used to provide an interface between a ComboCtrl and a -# ListCtrl that is used as the popoup for the combo widget. In this -# case we use multiple inheritance to derive from both wx.ListCtrl and -# wx.ComboPopup, but it also works well when deriving from just -# ComboPopup and using a has-a relationship with the popup control, -# you just need to be sure to return the control itself from the -# GetControl method. - -class ListCtrlComboPopup(wx.ListCtrl, wx.combo.ComboPopup): - - def __init__(self, log=None): - if log: - self.log = log - else: - self.log = NullLog() - - - # Since we are using multiple inheritance, and don't know yet - # which window is to be the parent, we'll do 2-phase create of - # the ListCtrl instead, and call its Create method later in - # our Create method. (See Create below.) - self.PostCreate(wx.PreListCtrl()) - - # Also init the ComboPopup base class. - wx.combo.ComboPopup.__init__(self) - + def __init__(self): + wx.ComboPopup.__init__(self) + self.lc = None def AddItem(self, txt): - self.InsertStringItem(self.GetItemCount(), txt) + self.lc.InsertItem(self.lc.GetItemCount(), txt) def OnMotion(self, evt): - item, flags = self.HitTest(evt.GetPosition()) + item, flags = self.lc.HitTest(evt.GetPosition()) if item >= 0: - self.Select(item) + self.lc.Select(item) self.curitem = item def OnLeftDown(self, evt): @@ -55,73 +33,59 @@ class ListCtrlComboPopup(wx.ListCtrl, wx.combo.ComboPopup): # ComboPopup base class. Most of them are not required, but all # are shown here for demonstration purposes. - # This is called immediately after construction finishes. You can # use self.GetCombo if needed to get to the ComboCtrl instance. def Init(self): - self.log.write("ListCtrlComboPopup.Init") self.value = -1 self.curitem = -1 - # Create the popup child control. Return true for success. def Create(self, parent): - self.log.write("ListCtrlComboPopup.Create") - wx.ListCtrl.Create(self, parent, - style=wx.LC_LIST|wx.LC_SINGLE_SEL|wx.SIMPLE_BORDER) - #self.Bind(wx.EVT_MOTION, self.OnMotion) - self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) + self.lc = wx.ListCtrl(parent, style=wx.LC_LIST | wx.LC_SINGLE_SEL | wx.SIMPLE_BORDER) + self.lc.Bind(wx.EVT_MOTION, self.OnMotion) + self.lc.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) return True - # Return the widget that is to be used for the popup def GetControl(self): - #self.log.write("ListCtrlComboPopup.GetControl") - return self + return self.lc # Called just prior to displaying the popup, you can use it to # 'select' the current item. def SetStringValue(self, val): - self.log.write("ListCtrlComboPopup.SetStringValue") - idx = self.FindItem(-1, val) + idx = self.lc.FindItem(-1, val) if idx != wx.NOT_FOUND: - self.Select(idx) + self.lc.Select(idx) # Return a string representation of the current item. def GetStringValue(self): - self.log.write("ListCtrlComboPopup.GetStringValue") if self.value >= 0: - return self.GetItemText(self.value) + return self.lc.GetItemText(self.value) return "" # Called immediately after the popup is shown def OnPopup(self): - self.log.write("ListCtrlComboPopup.OnPopup") - wx.combo.ComboPopup.OnPopup(self) + wx.ComboPopup.OnPopup(self) # Called when popup is dismissed def OnDismiss(self): - self.log.write("ListCtrlComboPopup.OnDismiss") - wx.combo.ComboPopup.OnDismiss(self) + wx.ComboPopup.OnDismiss(self) # This is called to custom paint in the combo control itself # (ie. not the popup). Default implementation draws value as # string. def PaintComboControl(self, dc, rect): - self.log.write("ListCtrlComboPopup.PaintComboControl") - wx.combo.ComboPopup.PaintComboControl(self, dc, rect) + wx.ComboPopup.PaintComboControl(self, dc, rect) # Receives key events from the parent ComboCtrl. Events not # handled should be skipped, as usual. def OnComboKeyEvent(self, event): - self.log.write("ListCtrlComboPopup.OnComboKeyEvent") - wx.combo.ComboPopup.OnComboKeyEvent(self, event) + wx.ComboPopup.OnComboKeyEvent(self, event) # Implement if you need to support special action when user # double-clicks on the parent wxComboCtrl. def OnComboDoubleClick(self): - self.log.write("ListCtrlComboPopup.OnComboDoubleClick") - wx.combo.ComboPopup.OnComboDoubleClick(self) + wx.ComboPopup.OnComboDoubleClick(self) # Return final size of popup. Called on every popup, just prior to OnPopup. # minWidth = preferred minimum width for window @@ -129,243 +93,15 @@ class ListCtrlComboPopup(wx.ListCtrl, wx.combo.ComboPopup): # maxHeight = max height for window, as limited by screen size # and should only be rounded down, if necessary. def GetAdjustedSize(self, minWidth, prefHeight, maxHeight): - self.log.write("ListCtrlComboPopup.GetAdjustedSize: %d, %d, %d" % (minWidth, prefHeight, maxHeight)) - return wx.combo.ComboPopup.GetAdjustedSize(self, minWidth, prefHeight, maxHeight) + return wx.ComboPopup.GetAdjustedSize(self, minWidth, prefHeight, maxHeight) # Return true if you want delay the call to Create until the popup # is shown for the first time. It is more efficient, but note that # it is often more convenient to have the control created - # immediately. + # immediately. # Default returns false. def LazyCreate(self): - self.log.write("ListCtrlComboPopup.LazyCreate") - return wx.combo.ComboPopup.LazyCreate(self) - - - -#---------------------------------------------------------------------- -# This class is a popup containing a TreeCtrl. This time we'll use a -# has-a style (instead of is-a like above.) - -class TreeCtrlComboPopup(wx.combo.ComboPopup): - - # overridden ComboPopup methods - - def Init(self): - self.value = None - self.curitem = None - - - def Create(self, parent): - self.tree = wx.TreeCtrl(parent, style=wx.TR_HIDE_ROOT - |wx.TR_HAS_BUTTONS - |wx.TR_SINGLE - |wx.TR_LINES_AT_ROOT - |wx.SIMPLE_BORDER) - self.tree.Bind(wx.EVT_MOTION, self.OnMotion) - self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - - - def GetControl(self): - return self.tree - - - def GetStringValue(self): - if self.value: - return self.tree.GetItemText(self.value) - return "" - - - def OnPopup(self): - if self.value: - self.tree.EnsureVisible(self.value) - self.tree.SelectItem(self.value) - - - def SetStringValue(self, value): - # this assumes that item strings are unique... - root = self.tree.GetRootItem() - if not root: - return - found = self.FindItem(root, value) - if found: - self.value = found - self.tree.SelectItem(found) - - - def GetAdjustedSize(self, minWidth, prefHeight, maxHeight): - return wx.Size(minWidth, min(200, maxHeight)) - - - # helpers - - def FindItem(self, parentItem, text): - item, cookie = self.tree.GetFirstChild(parentItem) - while item: - if self.tree.GetItemText(item) == text: - return item - if self.tree.ItemHasChildren(item): - item = self.FindItem(item, text) - item, cookie = self.tree.GetNextChild(parentItem, cookie) - return wx.TreeItemId(); - - - def AddItem(self, value, parent=None): - if not parent: - root = self.tree.GetRootItem() - if not root: - root = self.tree.AddRoot("") - parent = root - - item = self.tree.AppendItem(parent, value) - return item - - - def OnMotion(self, evt): - # have the selection follow the mouse, like in a real combobox - item, flags = self.tree.HitTest(evt.GetPosition()) - if item and flags & wx.TREE_HITTEST_ONITEMLABEL: - self.tree.SelectItem(item) - self.curitem = item - evt.Skip() - - - def OnLeftDown(self, evt): - # do the combobox selection - item, flags = self.tree.HitTest(evt.GetPosition()) - if item and flags & wx.TREE_HITTEST_ONITEMLABEL: - self.curitem = item - self.value = item - self.Dismiss() - evt.Skip() - - -#---------------------------------------------------------------------- -# Here we subclass wx.combo.ComboCtrl to do some custom popup animation - -CUSTOM_COMBOBOX_ANIMATION_DURATION = 200 - -class ComboCtrlWithCustomPopupAnim(wx.combo.ComboCtrl): - def __init__(self, *args, **kw): - wx.combo.ComboCtrl.__init__(self, *args, **kw) - self.Bind(wx.EVT_TIMER, self.OnTimer) - self.aniTimer = wx.Timer(self) - - - def AnimateShow(self, rect, flags): - self.aniStart = wx.GetLocalTimeMillis() - self.aniRect = wx.Rect(*rect) - self.aniFlags = flags - - dc = wx.ScreenDC() - bmp = wx.EmptyBitmap(rect.width, rect.height) - mdc = wx.MemoryDC(bmp) - if "wxMac" in wx.PlatformInfo: - pass - else: - mdc.Blit(0, 0, rect.width, rect.height, dc, rect.x, rect.y) - del mdc - self.aniBackBitmap = bmp - - self.aniTimer.Start(10, wx.TIMER_CONTINUOUS) - self.OnTimer(None) - return False - - - def OnTimer(self, evt): - stopTimer = False - popup = self.GetPopupControl().GetControl() - rect = self.aniRect - dc = wx.ScreenDC() - - if self.IsPopupWindowState(self.Hidden): - stopTimer = True - else: - pos = wx.GetLocalTimeMillis() - self.aniStart - if pos < CUSTOM_COMBOBOX_ANIMATION_DURATION: - # Actual animation happens here - width = rect.width - height = rect.height - - center_x = rect.x + (width/2) - center_y = rect.y + (height/2) - - dc.SetPen( wx.BLACK_PEN ) - dc.SetBrush( wx.TRANSPARENT_BRUSH ) - - w = (((pos*256)/CUSTOM_COMBOBOX_ANIMATION_DURATION)*width)/256 - ratio = float(w) / float(width) - h = int(height * ratio) - - dc.DrawBitmap( self.aniBackBitmap, rect.x, rect.y ) - dc.DrawRectangle( center_x - w/2, center_y - h/2, w, h ) - else: - stopTimer = True - - if stopTimer: - dc.DrawBitmap( self.aniBackBitmap, rect.x, rect.y ) - popup.Move( (0, 0) ) - self.aniTimer.Stop() - self.DoShowPopup( rect, self.aniFlags ) - - -#---------------------------------------------------------------------- -# FileSelectorCombo displays a dialog instead of a popup control, it -# also uses a custom bitmap on the combo button. - -class FileSelectorCombo(wx.combo.ComboCtrl): - def __init__(self, *args, **kw): - wx.combo.ComboCtrl.__init__(self, *args, **kw) - - # make a custom bitmap showing "..." - bw, bh = 14, 16 - bmp = wx.EmptyBitmap(bw,bh) - dc = wx.MemoryDC(bmp) - - # clear to a specific background colour - bgcolor = wx.Colour(255,254,255) - dc.SetBackground(wx.Brush(bgcolor)) - dc.Clear() - - # draw the label onto the bitmap - label = "..." - font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) - font.SetWeight(wx.FONTWEIGHT_BOLD) - dc.SetFont(font) - tw,th = dc.GetTextExtent(label) - dc.DrawText(label, (bw-tw)/2, (bw-tw)/2) - del dc - - # now apply a mask using the bgcolor - bmp.SetMaskColour(bgcolor) - - # and tell the ComboCtrl to use it - self.SetButtonBitmaps(bmp, True) - - self.Bind(wx.EVT_TEXT, self.onText) - - def onText(self, evt): - print 'EVT_TEXT:', self.GetValue() - evt.Skip() - - # Overridden from ComboCtrl, called when the combo button is clicked - def OnButtonClick(self): - path = "" - name = "" - if self.GetValue(): - path, name = os.path.split(self.GetValue()) - - dlg = wx.FileDialog(self, "Choose File", path, name, - "All files (*.*)|*.*", wx.FD_OPEN) - if dlg.ShowModal() == wx.ID_OK: - self.SetValue(dlg.GetPath()) - dlg.Destroy() - self.SetFocus() - - # Overridden from ComboCtrl to avoid assert since there is no ComboPopup - def DoSetPopupControl(self, popup): - pass - + return wx.ComboPopup.LazyCreate(self) #---------------------------------------------------------------------- @@ -375,82 +111,18 @@ class TestPanel(wx.Panel): self.log = log wx.Panel.__init__(self, parent, -1) - fgs = wx.FlexGridSizer(cols=3, hgap=10, vgap=10) + comboCtrl = wx.ComboCtrl(self, wx.ID_ANY, "") - cc = self.MakeLCCombo(log=self.log) - fgs.Add(cc) - fgs.Add((10,10)) - fgs.Add(wx.StaticText(self, -1, "wx.ComboCtrl with a ListCtrl popup")) + popupCtrl = ListCtrlComboPopup() - cc = self.MakeLCCombo(style=wx.CB_READONLY) - fgs.Add(cc) - fgs.Add((10,10)) - fgs.Add(wx.StaticText(self, -1, " Read-only")) + # It is important to call SetPopupControl() as soon as possible + comboCtrl.SetPopupControl(popupCtrl) - cc = self.MakeLCCombo() - cc.SetButtonPosition(side=wx.LEFT) - fgs.Add(cc) - fgs.Add((10,10)) - fgs.Add(wx.StaticText(self, -1, " Button on the left")) + # Populate using wx.ListView methods + popupCtrl.AddItem("First Item") + popupCtrl.AddItem("Second Item") + popupCtrl.AddItem("Third Item") - cc = self.MakeLCCombo() - cc.SetPopupMaxHeight(250) - fgs.Add(cc) - fgs.Add((10,10)) - fgs.Add(wx.StaticText(self, -1, " Max height of popup set")) - - cc = wx.combo.ComboCtrl(self, size=(250,-1)) - tcp = TreeCtrlComboPopup() - cc.SetPopupControl(tcp) - fgs.Add(cc) - fgs.Add((10,10)) - fgs.Add(wx.StaticText(self, -1, "TreeCtrl popup")) - # add some items to the tree - for i in range(5): - item = tcp.AddItem('Item %d' % (i+1)) - for j in range(15): - tcp.AddItem('Subitem %d-%d' % (i+1, j+1), parent=item) - - cc = ComboCtrlWithCustomPopupAnim(self, size=(250, -1)) - popup = ListCtrlComboPopup() - cc.SetPopupMaxHeight(150) - cc.SetPopupControl(popup) - fgs.Add(cc) - fgs.Add((10,10)) - fgs.Add(wx.StaticText(self, -1, "Custom popup animation")) - for word in "How cool was that!? Way COOL!".split(): - popup.AddItem(word) - if "wxMac" in wx.PlatformInfo: - cc.SetValue("Sorry, animation not working yet on Mac") - - - cc = FileSelectorCombo(self, size=(250, -1)) - fgs.Add(cc) - fgs.Add((10,10)) - fgs.Add(wx.StaticText(self, -1, "Custom popup action, and custom button bitmap")) - - box = wx.BoxSizer() - box.Add(fgs, 1, wx.EXPAND|wx.ALL, 20) - self.SetSizer(box) - - - def MakeLCCombo(self, log=None, style=0): - # Create a ComboCtrl - cc = wx.combo.ComboCtrl(self, style=style, size=(250,-1)) - - # Create a Popup - popup = ListCtrlComboPopup(log) - - # Associate them with each other. This also triggers the - # creation of the ListCtrl. - cc.SetPopupControl(popup) - - # Add some items to the listctrl. - for x in range(75): - popup.AddItem("Item-%02d" % x) - - return cc - #---------------------------------------------------------------------- diff --git a/demo/CommandLinkButton.py b/demo/CommandLinkButton.py index 5b0e1bf9..f7ae7986 100644 --- a/demo/CommandLinkButton.py +++ b/demo/CommandLinkButton.py @@ -1,5 +1,6 @@ import wx +import wx.adv #---------------------------------------------------------------------- @@ -8,7 +9,7 @@ class TestPanel(wx.Panel): self.log = log wx.Panel.__init__(self, parent, -1) - cmd = wx.CommandLinkButton(self, -1, + cmd = wx.adv.CommandLinkButton(self, -1, "wx.CommandLinkButton", """\ This type of button includes both a main label and a 'note' that is meant to diff --git a/demo/Cursor.py b/demo/Cursor.py index ade91686..d20eaf46 100644 --- a/demo/Cursor.py +++ b/demo/Cursor.py @@ -89,15 +89,15 @@ class TestPanel(wx.Panel): image = images.Pointy.GetImage() # since this image didn't come from a .cur file, tell it where the hotspot is - image.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 1) - image.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 1) + image.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 1) + image.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 1) # make the image into a cursor cursor = wx.CursorFromImage(image) else: # create one of the stock (built-in) cursors - cursor = wx.StockCursor(cnum) + cursor = wx.Cursor(cnum) # set the cursor for the window self.win.SetCursor(cursor) diff --git a/demo/CustomDragAndDrop.py b/demo/CustomDragAndDrop.py index 42fd4006..8234fcc2 100644 --- a/demo/CustomDragAndDrop.py +++ b/demo/CustomDragAndDrop.py @@ -24,36 +24,33 @@ class DoodlePad(wx.Window): def SetMode(self, mode): self.mode = mode if self.mode == "Draw": - self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL)) + self.SetCursor(wx.Cursor(wx.CURSOR_PENCIL)) else: self.SetCursor(wx.STANDARD_CURSOR) - def OnPaint(self, event): dc = wx.PaintDC(self) self.DrawSavedLines(dc) def DrawSavedLines(self, dc): - dc.BeginDrawing() + # dc.BeginDrawing() dc.SetPen(wx.Pen(wx.BLUE, 3)) for line in self.lines: for coords in line: dc.DrawLine(*coords) - dc.EndDrawing() - + # dc.EndDrawing() def OnLeftDown(self, event): if self.mode == "Drag": self.StartDragOpperation() elif self.mode == "Draw": self.curLine = [] - self.x, self.y = event.GetPositionTuple() + self.x, self.y = event.GetPosition() self.CaptureMouse() else: wx.Bell() self.log.write("unknown mode!\n") - def OnLeftUp(self, event): if self.HasCapture(): self.lines.append(self.curLine) @@ -67,14 +64,14 @@ class DoodlePad(wx.Window): def OnMotion(self, event): if self.HasCapture() and event.Dragging() and not self.mode == "Drag": dc = wx.ClientDC(self) - dc.BeginDrawing() + # dc.BeginDrawing() dc.SetPen(wx.Pen(wx.BLUE, 3)) - coords = (self.x, self.y) + event.GetPositionTuple() + evtPos = event.GetPosition() + coords = (self.x, self.y) + (evtPos.x, evtPos.y) self.curLine.append(coords) dc.DrawLine(*coords) - self.x, self.y = event.GetPositionTuple() - dc.EndDrawing() - + self.x, self.y = event.GetPosition() + # dc.EndDrawing() def StartDragOpperation(self): # pickle the lines list @@ -87,7 +84,7 @@ class DoodlePad(wx.Window): # Also create a Bitmap version of the drawing size = self.GetSize() - bmp = wx.EmptyBitmap(size.width, size.height) + bmp = wx.Bitmap(size.width, size.height) dc = wx.MemoryDC() dc.SelectObject(bmp) dc.SetBackground(wx.WHITE_BRUSH) @@ -153,7 +150,6 @@ class DoodleDropTarget(wx.DropTarget): return d - # Called when OnDrop returns True. We need to get the data and # do something with it. def OnData(self, x, y, d): @@ -165,12 +161,11 @@ class DoodleDropTarget(wx.DropTarget): linesdata = self.data.GetData() lines = cPickle.loads(linesdata) self.dv.SetLines(lines) - + # what is returned signals the source what to do # with the original data (move, copy, etc.) In this # case we just return the suggested value given to us. - return d - + return d class DoodleViewer(wx.Window): @@ -194,13 +189,13 @@ class DoodleViewer(wx.Window): self.DrawSavedLines(dc) def DrawSavedLines(self, dc): - dc.BeginDrawing() + # dc.BeginDrawing() dc.SetPen(wx.Pen(wx.RED, 3)) for line in self.lines: for coords in line: dc.DrawLine(*coords) - dc.EndDrawing() + # dc.EndDrawing() #---------------------------------------------------------------------- @@ -300,13 +295,14 @@ def runTest(frame, nb, log): if __name__ == '__main__': import sys - + class DummyLog: def WriteText(self, text): sys.stdout.write(text) class TestApp(wx.App): def OnInit(self): + wx.InitAllImageHandlers() self.MakeFrame() return True diff --git a/demo/DVC_CustomRenderer.py b/demo/DVC_CustomRenderer.py index 4a65a2ec..4d5cb3c2 100644 --- a/demo/DVC_CustomRenderer.py +++ b/demo/DVC_CustomRenderer.py @@ -38,7 +38,7 @@ class MyCustomRenderer(dv.PyDataViewCustomRenderer): dc.SetBrush(wx.Brush('light grey')) dc.SetPen(wx.TRANSPARENT_PEN) rect.Deflate(1, 1) - dc.DrawRoundedRectangleRect(rect, 2) + dc.DrawRoundedRectangle(rect, 2) # And then finish up with this helper function that draws the # text for us, dealing with alignment, font and color diff --git a/demo/DVC_DataViewModel.py b/demo/DVC_DataViewModel.py index b832f512..016511f3 100644 --- a/demo/DVC_DataViewModel.py +++ b/demo/DVC_DataViewModel.py @@ -10,7 +10,7 @@ import random def makeBlank(self): # Just a little helper function to make an empty image for our # model to use. - empty = wx.EmptyBitmap(16,16,32) + empty = wx.Bitmap(16,16,32) dc = wx.MemoryDC(empty) dc.SetBackground(wx.Brush((0,0,0,0))) dc.Clear() @@ -32,17 +32,17 @@ class Song(object): d = random.choice(range(27))+1 m = random.choice(range(12)) y = random.choice(range(1980, 2005)) - self.date = wx.DateTimeFromDMY(d,m,y) - + self.date = wx.DateTime().FromDMY(d,m,y) + def __repr__(self): return 'Song: %s-%s' % (self.artist, self.title) - + class Genre(object): def __init__(self, name): self.name = name self.songs = [] - + def __repr__(self): return 'Genre: ' + self.name @@ -50,13 +50,13 @@ class Genre(object): # This model acts as a bridge between the DataViewCtrl and the music data, and # organizes it hierarchically as a collection of Genres, each of which is a -# collection of songs. We derive the class from PyDataViewModel, which knows +# collection of songs. We derive the class from PyDataViewCtrl, which knows # how to reflect the C++ virtual methods to the Python methods in the derived # class. # This model provides these data columns: # -# 0. Genre: string +# 0. Genre : string # 1. Artist: string # 2. Title: string # 3. id: integer @@ -69,7 +69,7 @@ class MyTreeListModel(dv.PyDataViewModel): dv.PyDataViewModel.__init__(self) self.data = data self.log = log - + # The objmapper is an instance of DataViewItemObjectMapper and is used # to help associate Python objects with DataViewItem objects. Normally # a dictionary is used so any Python object can be used as data nodes. @@ -80,7 +80,7 @@ class MyTreeListModel(dv.PyDataViewModel): # self.ItemToObject methods used below. self.objmapper.UseWeakRefs(True) - + # Report how many columns this model provides data for. def GetColumnCount(self): return 6 @@ -95,9 +95,9 @@ class MyTreeListModel(dv.PyDataViewModel): 5 : 'bool', } return mapper[col] - - - def GetChildren(self, parent, children): + + + def GetChildren(self, parent, children): # The view calls this method to find the children of any node in the # control. There is an implicit hidden root node, and the top level # item(s) should be reported as children of this node. A List view @@ -105,7 +105,7 @@ class MyTreeListModel(dv.PyDataViewModel): # view adds additional items as children of the other items, as needed, # to provide the tree hierachy. ##self.log.write("GetChildren\n") - + # If the parent item is invalid then it represents the hidden root # item, so we'll use the genre objects as its children and they will # end up being the collection of visible roots in our tree. @@ -113,7 +113,7 @@ class MyTreeListModel(dv.PyDataViewModel): for genre in self.data: children.append(self.ObjectToItem(genre)) return len(self.data) - + # Otherwise we'll fetch the python object associated with the parent # item and make DV items for each of it's child objects. node = self.ItemToObject(parent) @@ -122,12 +122,12 @@ class MyTreeListModel(dv.PyDataViewModel): children.append(self.ObjectToItem(song)) return len(node.songs) return 0 - + def IsContainer(self, item): # Return True if the item has children, False otherwise. ##self.log.write("IsContainer\n") - + # The hidden root is a container if not item: return True @@ -136,38 +136,38 @@ class MyTreeListModel(dv.PyDataViewModel): if isinstance(node, Genre): return True # but everything else (the song objects) are not - return False + return False #def HasContainerColumns(self, item): # self.log.write('HasContainerColumns\n') # return True - + def GetParent(self, item): # Return the item which is this item's parent. ##self.log.write("GetParent\n") - + if not item: return dv.NullDataViewItem - node = self.ItemToObject(item) + node = self.ItemToObject(item) if isinstance(node, Genre): return dv.NullDataViewItem elif isinstance(node, Song): for g in self.data: if g.name == node.genre: return self.ObjectToItem(g) - - + + def GetValue(self, item, col): # Return the value to be displayed for this item and column. For this # example we'll just pull the values from the data objects we # associated with the items in GetChildren. - + # Fetch the data object for this item. node = self.ItemToObject(item) - + if isinstance(node, Genre): # We'll only use the first column for the Genre objects, # for the other columns lets just return empty values @@ -179,8 +179,8 @@ class MyTreeListModel(dv.PyDataViewModel): 5 : False, } return mapper[col] - - + + elif isinstance(node, Song): mapper = { 0 : node.genre, 1 : node.artist, @@ -190,10 +190,10 @@ class MyTreeListModel(dv.PyDataViewModel): 5 : node.like, } return mapper[col] - + else: raise RuntimeError("unknown node type") - + def GetAttr(self, item, col, attr): @@ -204,14 +204,14 @@ class MyTreeListModel(dv.PyDataViewModel): attr.SetBold(True) return True return False - - + + def SetValue(self, value, item, col): self.log.write("SetValue: %s\n" % value) - + # We're not allowing edits in column zero (see below) so we just need # to deal with Song objects and cols 1 - 5 - + node = self.ItemToObject(item) if isinstance(node, Song): if col == 1: @@ -224,7 +224,7 @@ class MyTreeListModel(dv.PyDataViewModel): node.date = value elif col == 5: node.like = value - + #---------------------------------------------------------------------- @@ -241,17 +241,17 @@ class TestPanel(wx.Panel): | dv.DV_VERT_RULES | dv.DV_MULTIPLE ) - + # Create an instance of our model... if model is None: self.model = MyTreeListModel(data, log) else: - self.model = model + self.model = model # Tel the DVC to use the model self.dvc.AssociateModel(self.model) - # Define the columns that we want in the view. Notice the + # Define the columns that we want in the view. Notice the # parameter which tells the view which col in the data model to pull # values from for each view column. if 1: @@ -263,41 +263,41 @@ class TestPanel(wx.Panel): self.dvc.AppendColumn(c0) else: self.dvc.AppendTextColumn("Genre", 0, width=80) - + c1 = self.dvc.AppendTextColumn("Artist", 1, width=170, mode=dv.DATAVIEW_CELL_EDITABLE) c2 = self.dvc.AppendTextColumn("Title", 2, width=260, mode=dv.DATAVIEW_CELL_EDITABLE) c3 = self.dvc.AppendDateColumn('Acquired', 4, width=100, mode=dv.DATAVIEW_CELL_ACTIVATABLE) c4 = self.dvc.AppendToggleColumn('Like', 5, width=40, mode=dv.DATAVIEW_CELL_ACTIVATABLE) - + # Notice how we pull the data from col 3, but this is the 6th col # added to the DVC. The order of the view columns is not dependent on # the order of the model columns at all. c5 = self.dvc.AppendTextColumn("id", 3, width=40, mode=dv.DATAVIEW_CELL_EDITABLE) c5.Alignment = wx.ALIGN_RIGHT - + # Set some additional attributes for all the columns for c in self.dvc.Columns: c.Sortable = True c.Reorderable = True - + self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.Add(self.dvc, 1, wx.EXPAND) - + b1 = wx.Button(self, label="New View", name="newView") self.Bind(wx.EVT_BUTTON, self.OnNewView, b1) - + self.Sizer.Add(b1, 0, wx.ALL, 5) - - + + def OnNewView(self, evt): f = wx.Frame(None, title="New view, shared model", size=(600,400)) TestPanel(f, self.log, model=self.model) b = f.FindWindowByName("newView") b.Disable() f.Show() - - + + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/DVC_IndexListModel.py b/demo/DVC_IndexListModel.py index cedc022e..5105221c 100644 --- a/demo/DVC_IndexListModel.py +++ b/demo/DVC_IndexListModel.py @@ -17,9 +17,9 @@ import wx.dataview as dv # For this example our data is stored in a simple list of lists. In # real life you can use whatever you want or need to hold your data. -class TestModel(dv.PyDataViewIndexListModel): +class TestModel(dv.DataViewIndexListModel): def __init__(self, data, log): - dv.PyDataViewIndexListModel.__init__(self, len(data)) + dv.DataViewIndexListModel.__init__(self, len(data)) self.data = data self.log = log @@ -46,7 +46,7 @@ class TestModel(dv.PyDataViewIndexListModel): def GetCount(self): #self.log.write('GetCount') return len(self.data) - + # Called to check if non-standard attributes should be used in the # cell at (row, col) def GetAttrByRow(self, row, col, attr): @@ -74,28 +74,28 @@ class TestModel(dv.PyDataViewIndexListModel): else: return cmp(self.data[row1][col], self.data[row2][col]) - + def DeleteRows(self, rows): # make a copy since we'll be sorting(mutating) the list rows = list(rows) # use reverse order so the indexes don't change as we remove items rows.sort(reverse=True) - + for row in rows: # remove it from our data structure del self.data[row] # notify the view(s) using this model that it has been removed self.RowDeleted(row) - - + + def AddRow(self, value): # update data structure self.data.append(value) # notify views self.RowAppended() - - + + class TestPanel(wx.Panel): def __init__(self, parent, log, model=None, data=None): self.log = log @@ -109,12 +109,12 @@ class TestPanel(wx.Panel): | dv.DV_VERT_RULES | dv.DV_MULTIPLE ) - + # Create an instance of our simple model... if model is None: self.model = TestModel(data, log) else: - self.model = model + self.model = model # ...and associate it with the dataview control. Models can # be shared between multiple DataViewCtrls, so this does not @@ -158,9 +158,9 @@ class TestPanel(wx.Panel): c0.Reorderable = False # set the Sizer property (same as SetSizer) - self.Sizer = wx.BoxSizer(wx.VERTICAL) + self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.Add(self.dvc, 1, wx.EXPAND) - + # Add some buttons to help out with the tests b1 = wx.Button(self, label="New View", name="newView") self.Bind(wx.EVT_BUTTON, self.OnNewView, b1) @@ -196,7 +196,7 @@ class TestPanel(wx.Panel): rows = [self.model.GetRow(item) for item in items] self.model.DeleteRows(rows) - + def OnAddRow(self, evt): # Add some bogus data to a new row in the model's data id = len(self.model.data) + 1 @@ -205,7 +205,7 @@ class TestPanel(wx.Panel): 'new title %d' % id, 'genre %d' % id] self.model.AddRow(value) - + def OnEditingDone(self, evt): self.log.write("OnEditingDone\n") @@ -213,7 +213,7 @@ class TestPanel(wx.Panel): def OnValueChanged(self, evt): self.log.write("OnValueChanged\n") - + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/DVC_ListCtrl.py b/demo/DVC_ListCtrl.py index 626bfbe5..543d9ec7 100644 --- a/demo/DVC_ListCtrl.py +++ b/demo/DVC_ListCtrl.py @@ -25,17 +25,17 @@ class TestPanel(wx.Panel): dvlc.AppendTextColumn('artist', width=170) dvlc.AppendTextColumn('title', width=260) dvlc.AppendTextColumn('genre', width=80) - + # Load the data. Each item (row) is added as a sequence of values # whose order matches the columns for itemvalues in musicdata: dvlc.AppendItem(itemvalues) - + # Set the layout so the listctrl fills the panel self.Sizer = wx.BoxSizer() self.Sizer.Add(dvlc, 1, wx.EXPAND) - - + + #---------------------------------------------------------------------- diff --git a/demo/DVC_TreeCtrl.py b/demo/DVC_TreeCtrl.py index aab6c4bc..fe2c200b 100644 --- a/demo/DVC_TreeCtrl.py +++ b/demo/DVC_TreeCtrl.py @@ -16,9 +16,9 @@ class TestPanel(wx.Panel): isz = (16,16) il = wx.ImageList(*isz) - fldridx = il.AddIcon(wx.ArtProvider.GetIcon(wx.ART_FOLDER, wx.ART_OTHER, isz)) - fldropenidx = il.AddIcon(wx.ArtProvider.GetIcon(wx.ART_FOLDER_OPEN, wx.ART_OTHER, isz)) - fileidx = il.AddIcon(wx.ArtProvider.GetIcon(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz)) + fldridx = il.Add(wx.ArtProvider.GetIcon(wx.ART_FOLDER, wx.ART_OTHER, isz)) + fldropenidx = il.Add(wx.ArtProvider.GetIcon(wx.ART_FOLDER_OPEN, wx.ART_OTHER, isz)) + fileidx = il.Add(wx.ArtProvider.GetIcon(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz)) dvtc.SetImageList(il) self.root = dvtc.AppendContainer(dv.NullDataViewItem, @@ -41,8 +41,8 @@ class TestPanel(wx.Panel): # Set the layout so the treectrl fills the panel self.Sizer = wx.BoxSizer() self.Sizer.Add(dvtc, 1, wx.EXPAND) - - + + #---------------------------------------------------------------------- diff --git a/demo/DatePickerCtrl.py b/demo/DatePickerCtrl.py index a738af18..661691a3 100644 --- a/demo/DatePickerCtrl.py +++ b/demo/DatePickerCtrl.py @@ -1,5 +1,6 @@ import wx +import wx.adv #---------------------------------------------------------------------- @@ -11,22 +12,22 @@ class TestPanel(wx.Panel): sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) - dpc = wx.DatePickerCtrl(self, size=(120,-1), - style = wx.DP_DROPDOWN - | wx.DP_SHOWCENTURY - | wx.DP_ALLOWNONE ) - self.Bind(wx.EVT_DATE_CHANGED, self.OnDateChanged, dpc) + dpc = wx.adv.DatePickerCtrl(self, size=(120,-1), + style = wx.adv.DP_DROPDOWN + | wx.adv.DP_SHOWCENTURY + | wx.adv.DP_ALLOWNONE ) + self.Bind(wx.adv.EVT_DATE_CHANGED, self.OnDateChanged, dpc) sizer.Add(dpc, 0, wx.ALL, 50) # In some cases the widget used above will be a native date - # picker, so show the generic one too. - dpc = wx.GenericDatePickerCtrl(self, size=(120,-1), - style = wx.TAB_TRAVERSAL - | wx.DP_DROPDOWN - | wx.DP_SHOWCENTURY - | wx.DP_ALLOWNONE ) - self.Bind(wx.EVT_DATE_CHANGED, self.OnDateChanged, dpc) - sizer.Add(dpc, 0, wx.LEFT, 50) + # picker, so show the generic one too. + # dpc = wx.adv.DatePickerCtrlGeneric(self, size=(120,-1), + # style = wx.TAB_TRAVERSAL + # | wx.adv.DP_DROPDOWN + # | wx.adv.DP_SHOWCENTURY + # | wx.adv.DP_ALLOWNONE ) + # self.Bind(wx.adv.EVT_DATE_CHANGED, self.OnDateChanged, dpc) + # sizer.Add(dpc, 0, wx.LEFT, 50) def OnDateChanged(self, evt): diff --git a/demo/Dialog.py b/demo/Dialog.py index 611eea54..3ac95c25 100644 --- a/demo/Dialog.py +++ b/demo/Dialog.py @@ -11,22 +11,16 @@ wx.HelpProvider.Set(provider) class TestDialog(wx.Dialog): def __init__( - self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE, + self, parent, id, title, size=wx.DefaultSize, pos=wx.DefaultPosition, + style=wx.DEFAULT_DIALOG_STYLE, name='dialog' ): # Instead of calling wx.Dialog.__init__ we precreate the dialog # so we can set an extra style that must be set before # creation, and then we create the GUI object using the Create # method. - pre = wx.PreDialog() - pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) - pre.Create(parent, ID, title, pos, size, style) - - # This next step is the most important, it turns this Python - # object into the real wrapper of the dialog (instead of pre) - # as far as the wxPython extension is concerned. - self.PostCreate(pre) + wx.Dialog.__init__(self, parent, id, title, pos, size, style, name) + self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) # Now continue with the normal construction of the dialog # contents diff --git a/demo/DialogUnits.py b/demo/DialogUnits.py index 975eb175..586f7f98 100644 --- a/demo/DialogUnits.py +++ b/demo/DialogUnits.py @@ -6,7 +6,7 @@ # Author: Robin Dunn # # Created: A long time ago, in a galaxy far, far away... -# RCS-ID: $Id$ +# RCS-ID: $Id: DialogUnits.py 25140 2004-01-13 03:17:17Z RD $ # Copyright: (c) 1998 by Total Control Software # Licence: wxWindows license #---------------------------------------------------------------------------- diff --git a/demo/DragAndDrop.py b/demo/DragAndDrop.py index 95b192db..029b1b44 100644 --- a/demo/DragAndDrop.py +++ b/demo/DragAndDrop.py @@ -94,9 +94,9 @@ class ClipTextPanel(wx.Panel): #---------------------------------------------------------------------- -class OtherDropTarget(wx.PyDropTarget): +class OtherDropTarget(wx.DropTarget): def __init__(self, window, log): - wx.PyDropTarget.__init__(self) + wx.DropTarget.__init__(self) self.log = log self.do = wx.FileDataObject() self.SetDataObject(self.do) diff --git a/demo/DragImage.py b/demo/DragImage.py index 6b065d9b..f2ec5174 100644 --- a/demo/DragImage.py +++ b/demo/DragImage.py @@ -21,7 +21,7 @@ class DragShape: self.bmp.GetWidth(), self.bmp.GetHeight()) def Draw(self, dc, op = wx.COPY): - if self.bmp.Ok(): + if self.bmp.IsOk(): memDC = wx.MemoryDC() memDC.SelectObject(self.bmp) diff --git a/demo/DrawXXXList.py b/demo/DrawXXXList.py index 5086b14c..6e6f4210 100644 --- a/demo/DrawXXXList.py +++ b/demo/DrawXXXList.py @@ -132,7 +132,7 @@ def makeRandomColors(num): for i in range(num): c = random.choice(colours) - colors.append(wx.NamedColour(c)) + colors.append(wx.Colour(c)) return colors @@ -187,7 +187,7 @@ def Init(w, h, n): def TestPoints(dc,log): - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() dc.SetPen(wx.Pen("BLACK", 4)) @@ -195,7 +195,7 @@ def TestPoints(dc,log): dc.DrawPointList(points, wx.Pen("RED", 2)) dc.DrawPointList(points, pens) - dc.EndDrawing() + # dc.EndDrawing() log.write("DrawTime: %s seconds with DrawPointList\n" % (time.time() - start)) @@ -203,7 +203,7 @@ def TestArrayPoints(dc,log): try: import Numeric - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() dc.SetPen(wx.Pen("BLACK", 1)) @@ -212,7 +212,7 @@ def TestArrayPoints(dc,log): #dc.DrawPointList(Apoints, wx.Pen("RED", 2)) #dc.DrawPointList(Apoints, pens) - dc.EndDrawing() + # dc.EndDrawing() log.write("DrawTime: %s seconds with DrawPointList an Numpy Array\n" % (time.time() - start)) except ImportError: log.write("Couldn't import Numeric") @@ -220,7 +220,7 @@ def TestArrayPoints(dc,log): def TestLines(dc,log): - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() dc.SetPen(wx.Pen("BLACK", 2)) @@ -228,12 +228,12 @@ def TestLines(dc,log): dc.DrawLineList(lines, wx.Pen("RED", 2)) dc.DrawLineList(lines, pens) - dc.EndDrawing() + # dc.EndDrawing() log.write("DrawTime: %s seconds with DrawLineList\n" % (time.time() - start)) def TestRectangles(dc,log): - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() dc.SetPen( wx.Pen("BLACK",1) ) @@ -248,12 +248,12 @@ def TestRectangles(dc,log): ## #dc.DrawRectangleList(rectangles,pens,brushes) ## dc.DrawRectangleList(rectangles) - dc.EndDrawing() + # dc.EndDrawing() log.write("DrawTime: %s seconds with DrawRectanglesList\n" % (time.time() - start)) def TestEllipses(dc,log): - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() dc.SetPen( wx.Pen("BLACK",1) ) @@ -266,7 +266,7 @@ def TestEllipses(dc,log): dc.DrawEllipseList(rectangles,None,brushes) dc.DrawEllipseList(rectangles,pens,brushes) - dc.EndDrawing() + # dc.EndDrawing() log.write("DrawTime: %s seconds with DrawEllipsesList\n" % (time.time() - start)) @@ -275,7 +275,7 @@ def TestRectanglesArray(dc,log): import Numeric Apoints = Numeric.array(rectangles) - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() dc.SetPen(wx.Pen("BLACK", 1)) dc.DrawRectangleList(rectangles) @@ -287,7 +287,7 @@ def TestRectanglesArray(dc,log): ## #dc.DrawRectangleList(rectangles,pens,brushes) ## dc.DrawRectangleList(rectangles) - dc.EndDrawing() + # dc.EndDrawing() log.write("DrawTime: %s seconds with DrawRectangleList and Numpy Array\n" % (time.time() - start)) except ImportError: log.write("Couldn't import Numeric") @@ -295,7 +295,7 @@ def TestRectanglesArray(dc,log): def TestRectanglesLoop(dc,log): - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() dc.DrawRectangleList(rectangles,pens,brushes) @@ -308,12 +308,12 @@ def TestRectanglesLoop(dc,log): dc.SetBrush( brushes[i] ) dc.DrawRectangle(rectangles[i][0],rectangles[i][1],rectangles[i][2],rectangles[i][3]) - dc.EndDrawing() + # dc.EndDrawing() log.write("DrawTime: %s seconds with Python loop\n" % (time.time() - start)) def TestPolygons(dc,log): - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() dc.SetPen(wx.Pen("BLACK", 1)) @@ -324,11 +324,11 @@ def TestPolygons(dc,log): dc.DrawPolygonList(polygons,None,brushes) log.write("DrawTime: %s seconds with DrawPolygonList\n" % (time.time() - start)) - dc.EndDrawing() + # dc.EndDrawing() def TestText(dc,log): - dc.BeginDrawing() + # dc.BeginDrawing() start = time.time() @@ -340,7 +340,7 @@ def TestText(dc,log): log.write("DrawTime: %s seconds with DrawTextList\n" % (time.time() - start)) - dc.EndDrawing() + # dc.EndDrawing() diff --git a/demo/EventManager.py b/demo/EventManager.py index 7f794289..bcc4dfbe 100644 --- a/demo/EventManager.py +++ b/demo/EventManager.py @@ -9,8 +9,8 @@ # Licence: wxWindows license #--------------------------------------------------------------------------- -import wx -import wx.lib.evtmgr as em +import wx +import wx.lib.evtmgr as em #---------------------------------------------------------------------- @@ -20,9 +20,9 @@ class TestPanel(wx.Panel): self.log = log fsize = self.GetFont().GetPointSize() - f1 = wx.Font(fsize+0, wx.SWISS, wx.NORMAL, wx.NORMAL) - f2 = wx.Font(fsize+2, wx.SWISS, wx.NORMAL, wx.BOLD) - f3 = wx.Font(fsize+6, wx.SWISS, wx.NORMAL, wx.BOLD) + f1 = wx.Font(fsize+0, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) + f2 = wx.Font(fsize+2, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) + f3 = wx.Font(fsize+6, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) title1 = wx.StaticText(self, -1, 'EventManager') title1.SetFont(f3) @@ -111,7 +111,7 @@ class Tile(wx.Window): def doLayout(self, event): self.Layout() - + def setHover(self, event): self.SetBackgroundColour(Tile.hover) @@ -128,7 +128,6 @@ class Tile(wx.Window): self.Refresh() - class InnerTile(wx.Window): IDLE_COLOR = wx.Colour( 80, 10, 10) START_COLOR = wx.Colour(200, 70, 50) @@ -181,7 +180,7 @@ class InnerTile(wx.Window): def makeColor(self, mouseEvent): - self.makeColorFromTuple(mouseEvent.GetPositionTuple()) + self.makeColorFromTuple(mouseEvent.GetPosition()) def makeColorFromTuple(self, (x, y)): @@ -194,8 +193,6 @@ class InnerTile(wx.Window): self.setColor(wx.Colour(int(r), int(g), int(b))) - - #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/FileDialog.py b/demo/FileDialog.py index da832540..0e56fcf7 100644 --- a/demo/FileDialog.py +++ b/demo/FileDialog.py @@ -38,13 +38,15 @@ class TestPanel(wx.Panel): # dialog is set up to change the current working directory to the path chosen. dlg = wx.FileDialog( self, message="Choose a file", - defaultDir=os.getcwd(), + defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, - style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR + style=wx.FD_OPEN | wx.FD_MULTIPLE | + wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST | + wx.FD_PREVIEW ) - # Show the dialog and retrieve the user response. If it is the OK response, + # Show the dialog and retrieve the user response. If it is the OK response, # process the data. if dlg.ShowModal() == wx.ID_OK: # This returns a Python list of files that were selected. @@ -63,7 +65,6 @@ class TestPanel(wx.Panel): dlg.Destroy() - def OnButton2(self, evt): self.log.WriteText("CWD: %s\n" % os.getcwd()) @@ -75,15 +76,15 @@ class TestPanel(wx.Panel): # force the current working directory to change if the user chooses a different # directory than the one initially set. dlg = wx.FileDialog( - self, message="Save file as ...", defaultDir=os.getcwd(), - defaultFile="", wildcard=wildcard, style=wx.SAVE + self, message="Save file as ...", defaultDir=os.getcwd(), + defaultFile="", wildcard=wildcard, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT ) # This sets the default filter that the user will initially see. Otherwise, # the first filter in the list will be used by default. dlg.SetFilterIndex(2) - # Show the dialog and retrieve the user response. If it is the OK response, + # Show the dialog and retrieve the user response. If it is the OK response, # process the data. if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() @@ -92,7 +93,7 @@ class TestPanel(wx.Panel): # Normally, at this point you would save your data using the file and path # data that the user provided to you, but since we didn't actually start # with any data to work with, that would be difficult. - # + # # The code to do so would be similar to this, assuming 'data' contains # the data you want to save: # @@ -111,7 +112,6 @@ class TestPanel(wx.Panel): # BAD things can happen otherwise! dlg.Destroy() - #--------------------------------------------------------------------------- @@ -125,12 +125,12 @@ def runTest(frame, nb, log): overview = """\ This class provides the file selection dialog. It incorporates OS-native features -depending on the OS in use, and can be used both for open and save operations. +depending on the OS in use, and can be used both for open and save operations. The files displayed can be filtered by setting up a wildcard filter, multiple files can be selected (open only), and files can be forced in a read-only mode. There are two ways to get the results back from the dialog. GetFiles() returns only -the file names themselves, in a Python list. GetPaths() returns the full path and +the file names themselves, in a Python list. GetPaths() returns the full path and filenames combined as a Python list. """ diff --git a/demo/FileHistory.py b/demo/FileHistory.py index b94b4567..8a587229 100644 --- a/demo/FileHistory.py +++ b/demo/FileHistory.py @@ -5,11 +5,11 @@ import wx #---------------------------------------------------------------------- text = """\ -Right-click on the panel above the line to get a menu. This menu will -be managed by a FileHistory object and so the files you select will -automatically be added to the end of the menu and will be selectable -the next time the menu is viewed. The filename selected, either via the -Open menu item, or from the history, will be displayed in the log +Right-click on the panel above the line to get a menu. This menu will +be managed by a FileHistory object and so the files you select will +automatically be added to the end of the menu and will be selectable +the next time the menu is viewed. The filename selected, either via the +Open menu item, or from the history, will be displayed in the log window below. """ @@ -77,16 +77,14 @@ class TestPanel(wx.Panel): del self.filehistory self.menu.Destroy() - def OnRightClick(self, evt): self.PopupMenu(self.menu) - def OnFileOpenDialog(self, evt): dlg = wx.FileDialog(self, defaultDir = os.getcwd(), wildcard = "All Files|*", - style = wx.OPEN | wx.CHANGE_DIR) + style = wx.FD_OPEN | wx.FD_CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() @@ -97,7 +95,6 @@ class TestPanel(wx.Panel): dlg.Destroy() - def OnFileHistory(self, evt): # get the file based on the menu ID fileNum = evt.GetId() - wx.ID_FILE1 @@ -128,7 +125,7 @@ list appended to a menu, such as the File menu.

Note that this inclusion is not automatic; as illustrated in this example, you must add files (and remove them) as deemed necessary within the framework -of your program. +of your program.

Note also the additional cleanup required for this class, namely trapping the enclosing window's Destroy event and deleting the file history control and its diff --git a/demo/FindReplaceDialog.py b/demo/FindReplaceDialog.py index b27a83ce..dbe6f697 100644 --- a/demo/FindReplaceDialog.py +++ b/demo/FindReplaceDialog.py @@ -73,7 +73,7 @@ class TestPanel(wx.Panel): else: replaceTxt = "" - self.log.write("%s -- Find text: %s %s Flags: %d \n" % + self.log.write("%s -- Find text: %s Replace text: %s Flags: %d \n" % (evtType, evt.GetFindString(), replaceTxt, evt.GetFlags())) diff --git a/demo/FloatBar.py b/demo/FloatBar.py index 8f85d6e2..cb73bd13 100644 --- a/demo/FloatBar.py +++ b/demo/FloatBar.py @@ -22,7 +22,7 @@ class TestFloatBar(wx.Frame): win = wx.Window(self, -1) win.SetBackgroundColour("WHITE") wx.StaticText( - win, -1, "Drag the toolbar to float it,\n" + win, -1, "Drag the toolbar to float it,\n" "Toggle the last tool to remove\nthe title.", (15,15) ) @@ -38,26 +38,26 @@ class TestFloatBar(wx.Frame): copy_bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_TOOLBAR, tsize) paste_bmp= wx.ArtProvider.GetBitmap(wx.ART_PASTE, wx.ART_TOOLBAR, tsize) - tb.AddSimpleTool(10, new_bmp, "New", "Long help for 'New'") + tb.AddTool(10, "New", new_bmp, "Long help for 'New'") self.Bind(wx.EVT_TOOL, self.OnToolClick, id=10) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=10) - tb.AddSimpleTool(20, open_bmp, "Open") + tb.AddTool(20, "Open", open_bmp) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=20) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=20) tb.AddSeparator() - tb.AddSimpleTool(30, copy_bmp, "Copy") + tb.AddTool(30, "Copy", copy_bmp) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=30) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=30) - tb.AddSimpleTool(40, paste_bmp, "Paste") + tb.AddTool(40, "Paste", paste_bmp) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=40) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=40) tb.AddSeparator() - tb.AddCheckTool(60, images.Tog1.GetBitmap(), images.Tog2.GetBitmap()) + tb.AddCheckTool(60, "Check", images.Tog1.GetBitmap(), images.Tog2.GetBitmap(), "Check", "Long Help: Check", None) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=60) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=60) @@ -74,7 +74,7 @@ class TestFloatBar(wx.Frame): self.log.WriteText("tool %s clicked\n" % event.GetId()) if event.GetId() == 60: - print event.GetExtraLong(), event.IsChecked(), event.GetInt(), self.tb.GetToolState(60) + print(event.GetExtraLong(), event.IsChecked(), event.GetInt(), self.tb.GetToolState(60)) if event.GetExtraLong(): self.tb.SetTitle("") @@ -131,15 +131,3 @@ if __name__ == '__main__': import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) - - - - - - - - - - - - diff --git a/demo/FloatCanvas.py b/demo/FloatCanvas.py index 86919bd0..a8ec3272 100644 --- a/demo/FloatCanvas.py +++ b/demo/FloatCanvas.py @@ -438,7 +438,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import Canvas = self.Canvas Canvas.InitAll() - ## Random tests of everything: + ## Random tests of everything: colors = self.colors # Rectangles for i in range(3): @@ -1847,6 +1847,7 @@ if __name__ == "__main__": wx.App.__init__(self, *args, **kwargs) def OnInit(self): + wx.InitAllImageHandlers() DrawFrame = BuildDrawFrame() frame = DrawFrame(None, -1, "FloatCanvas Demo App",wx.DefaultPosition,(700,700)) diff --git a/demo/FontDialog.py b/demo/FontDialog.py index f5b9bcc9..253ee4dc 100644 --- a/demo/FontDialog.py +++ b/demo/FontDialog.py @@ -73,9 +73,9 @@ class TestPanel(wx.Panel): self.sampleText.SetFont(self.curFont) self.sampleText.SetForegroundColour(self.curClr) self.ps.SetLabel(str(self.curFont.GetPointSize())) - self.family.SetLabel(self.curFont.GetFamilyString()) - self.style.SetLabel(self.curFont.GetStyleString()) - self.weight.SetLabel(self.curFont.GetWeightString()) + self.family.SetLabel('%s' %self.curFont.GetFamily()) + self.style.SetLabel('%s' %self.curFont.GetStyle()) + self.weight.SetLabel('%s' %self.curFont.GetWeight()) self.face.SetLabel(self.curFont.GetFaceName()) self.nfi.SetLabel(self.curFont.GetNativeFontInfo().ToString()) self.Layout() @@ -88,7 +88,7 @@ class TestPanel(wx.Panel): data.SetInitialFont(self.curFont) dlg = wx.FontDialog(self, data) - + if dlg.ShowModal() == wx.ID_OK: data = dlg.GetFontData() font = data.GetChosenFont() @@ -117,15 +117,15 @@ def runTest(frame, nb, log): overview = """\ -This class allows you to use the system font selection dialog +This class allows you to use the system font selection dialog from within your program. Generally speaking, this allows you -to select a font by its name, font size, and weight, and +to select a font by its name, font size, and weight, and on some systems such things as strikethrough and underline. As with other dialogs used in wxPython, it is important to use the class' methods to extract the information you need about the font before you destroy the dialog. Failure -to observe this almost always leads to a program failure of +to observe this almost always leads to a program failure of some sort, often ugly. This demo serves two purposes; it shows how to use the dialog diff --git a/demo/FontEnumerator.py b/demo/FontEnumerator.py index 4356a5a8..f5ac9188 100644 --- a/demo/FontEnumerator.py +++ b/demo/FontEnumerator.py @@ -3,7 +3,6 @@ import wx #---------------------------------------------------------------------- - class TestPanel(wx.Panel): def __init__(self, parent, log): wx.Panel.__init__(self, parent, -1) @@ -35,13 +34,12 @@ class TestPanel(wx.Panel): self.lb1.SetSelection(0) self.OnSelect(None) - wx.FutureCall(300, self.SetTextSize) + wx.CallLater(300, self.SetTextSize) def SetTextSize(self): self.txt.SetSize(self.txt.GetBestSize()) - def OnSelect(self, evt): face = self.lb1.GetStringSelection() font = wx.Font(28, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, face) diff --git a/demo/Frame.py b/demo/Frame.py index 6a205094..b2abbf49 100644 --- a/demo/Frame.py +++ b/demo/Frame.py @@ -40,7 +40,7 @@ class TestPanel(wx.Panel): style = wx.DEFAULT_FRAME_STYLE) win.Show(True) - + #--------------------------------------------------------------------------- @@ -54,14 +54,14 @@ def runTest(frame, nb, log): overview = """\ -A Frame is a window whose size and position can (usually) be changed by -the user. It usually has thick borders and a title bar, and can optionally -contain a menu bar, toolbar and status bar. A frame can contain any window -that is not a Frame or Dialog. It is one of the most fundamental of the -wxWindows components. +A Frame is a window whose size and position can (usually) be changed by +the user. It usually has thick borders and a title bar, and can optionally +contain a menu bar, toolbar and status bar. A frame can contain any window +that is not a Frame or Dialog. It is one of the most fundamental of the +wxWindows components. -A Frame that has a status bar and toolbar created via the -CreateStatusBar / CreateToolBar functions manages +A Frame that has a status bar and toolbar created via the +CreateStatusBar / CreateToolBar functions manages these windows, and adjusts the value returned by GetClientSize to reflect the remaining size available to application windows. diff --git a/demo/GLCanvas.py b/demo/GLCanvas.py index 26635db4..3c7f3f7c 100644 --- a/demo/GLCanvas.py +++ b/demo/GLCanvas.py @@ -41,9 +41,9 @@ class ButtonPanel(wx.Panel): self.Bind(wx.EVT_BUTTON, self.OnButton, btn) #** Enable this to show putting a GLCanvas on the wx.Panel - if 1: + if 0: c = CubeCanvas(self) - c.SetMinSize((200, 200)) + c.SetSize((200, 200)) box.Add(c, 0, wx.ALIGN_CENTER|wx.ALL, 15) self.SetAutoLayout(True) diff --git a/demo/Gauge.py b/demo/Gauge.py index d53bcdbf..769c965e 100644 --- a/demo/Gauge.py +++ b/demo/Gauge.py @@ -12,7 +12,10 @@ class TestPanel(wx.Panel): wx.StaticText(self, -1, "This example shows the wx.Gauge control.", (45, 15)) self.g1 = wx.Gauge(self, -1, 50, (110, 50), (250, 25)) - self.g2 = wx.Gauge(self, -1, 50, (110, 95), (250, 25)) + self.g2 = wx.Gauge(self, -1, 75, (110, 95), (250, 25)) + self.g3 = wx.Gauge(self, -1, 100, (110, 135), (25, 100), wx.GA_VERTICAL) + # self.g3.SetBezelFace(12) + # self.g3.SetShadowWidth(8) self.Bind(wx.EVT_TIMER, self.TimerHandler) self.timer = wx.Timer(self) @@ -29,6 +32,7 @@ class TestPanel(wx.Panel): self.g1.SetValue(self.count) self.g2.Pulse() + self.g3.Pulse() #---------------------------------------------------------------------- diff --git a/demo/GenericButtons.py b/demo/GenericButtons.py index ff0ba020..5c6874dd 100644 --- a/demo/GenericButtons.py +++ b/demo/GenericButtons.py @@ -46,9 +46,9 @@ class TestPanel(wx.Panel): b.SetMinSize(wx.DefaultSize) b.SetBackgroundColour("Navy") b.SetForegroundColour(wx.WHITE) - b.SetToolTipString("This is a BIG button...") + b.SetToolTip("This is a BIG button...") # let the sizer set best size - sizer.Add(b, flag=wx.ADJUST_MINSIZE) + sizer.Add(b, flag=wx.ADJUST_MINSIZE) # An image button bmp = images.Test2.GetBitmap() @@ -138,8 +138,8 @@ class TestPanel(wx.Panel): b = buttons.ThemedGenToggleButton(self, -1, 'native renderered toggle') self.Bind(wx.EVT_BUTTON, self.OnButton, b) vbox.Add(b, 0, wx.ALL, 5) - - + + border = wx.BoxSizer(wx.VERTICAL) border.Add(sizer, 0, wx.ALL, 25) diff --git a/demo/GenericDirCtrl.py b/demo/GenericDirCtrl.py index 409abb15..1ebd1d47 100644 --- a/demo/GenericDirCtrl.py +++ b/demo/GenericDirCtrl.py @@ -6,17 +6,21 @@ import wx class TestPanel(wx.Panel): def __init__(self, parent, log): wx.Panel.__init__(self, parent, -1) + self.log = log txt1 = wx.StaticText(self, -1, "style=0") dir1 = wx.GenericDirCtrl(self, -1, size=(200,225), style=0) txt2 = wx.StaticText(self, -1, "wx.DIRCTRL_DIR_ONLY") - dir2 = wx.GenericDirCtrl(self, -1, size=(200,225), style=wx.DIRCTRL_DIR_ONLY|wx.DIRCTRL_MULTIPLE) + dir2 = wx.GenericDirCtrl(self, -1, size=(200,225), style=wx.DIRCTRL_DIR_ONLY) - txt3 = wx.StaticText(self, -1, "wx.DIRCTRL_SHOW_FILTERS") - dir3 = wx.GenericDirCtrl(self, -1, size=(200,225), style=wx.DIRCTRL_SHOW_FILTERS, - filter="All files (*.*)|*.*|Python files (*.py)|*.py") + txt3 = wx.StaticText(self, -1, "wx.DIRCTRL_SHOW_FILTERS\nwx.DIRCTRL_3D_INTERNAL\nwx.DIRCTRL_MULTIPLE") + dir3 = wx.GenericDirCtrl(self, -1, size=(200,225), + style=wx.DIRCTRL_SHOW_FILTERS | + wx.DIRCTRL_3D_INTERNAL | + wx.DIRCTRL_MULTIPLE, + filter="All files (*.*)|*.*|Python files (*.py)|*.py") sz = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) sz.Add((35, 35)) # some space above @@ -53,8 +57,8 @@ def runTest(frame, nb, log): overview = """\ This control can be used to place a directory listing (with optional files) -on an arbitrary window. The control contains a TreeCtrl window representing -the directory hierarchy, and optionally, a Choice window containing a list +on an arbitrary window. The control contains a TreeCtrl window representing +the directory hierarchy, and optionally, a Choice window containing a list of filters. The filters work in the same manner as in FileDialog. diff --git a/demo/GraphicsContext.py b/demo/GraphicsContext.py index 56a29667..3d997501 100644 --- a/demo/GraphicsContext.py +++ b/demo/GraphicsContext.py @@ -28,7 +28,7 @@ class TestPanel(wx.Panel): # the new size of the window. self.InitBuffer() evt.Skip() - + def OnPaint(self, evt): if USE_BUFFER: @@ -49,14 +49,14 @@ class TestPanel(wx.Panel): sz = self.GetClientSize() sz.width = max(1, sz.width) sz.height = max(1, sz.height) - self._buffer = wx.EmptyBitmap(sz.width, sz.height, 32) + self._buffer = wx.Bitmap(sz.width, sz.height, 32) dc = wx.MemoryDC(self._buffer) dc.SetBackground(wx.Brush(self.GetBackgroundColour())) dc.Clear() gc = self.MakeGC(dc) self.Draw(gc) - + def MakeGC(self, dc): try: @@ -76,19 +76,19 @@ class TestPanel(wx.Panel): # backend, (GDI+ on Windows, CoreGraphics on Mac, or # Cairo on GTK). gc = wx.GraphicsContext.Create(dc) - + except NotImplementedError: dc.DrawText("This build of wxPython does not support the wx.GraphicsContext " "family of classes.", 25, 25) return None return gc - - + + def Draw(self, gc): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetWeight(wx.BOLD) - gc.SetFont(font) + gc.SetFont(font, wx.BLACK) # make a path that contains a circle and some lines, centered at 0,0 path = gc.CreatePath() @@ -102,7 +102,7 @@ class TestPanel(wx.Panel): # Now use that path to demonstrate various capbilites of the grpahics context - gc.PushState() # save current translation/scale/other state + gc.PushState() # save current translation/scale/other state gc.Translate(60, 75) # reposition the context origin gc.SetPen(wx.Pen("navy", 1)) @@ -113,16 +113,16 @@ class TestPanel(wx.Panel): ("FillPath", gc.FillPath), ("DrawPath", gc.DrawPath)]: w, h = gc.GetTextExtent(label) - + gc.DrawText(label, -w/2, -BASE2-h-4) PathFunc(path) gc.Translate(2*BASE, 0) - + gc.PopState() # restore saved state gc.PushState() # save it again gc.Translate(60, 200) # offset to the lower part of the window - + gc.DrawText("Scale", 0, -BASE2) gc.Translate(0, 20) @@ -132,11 +132,11 @@ class TestPanel(wx.Panel): # (100,100), (0,100), (0,0) ]) #gc.ClipRegion(rgn) #gc.ResetClip() - + gc.SetBrush(wx.Brush(wx.Colour(178, 34, 34, 128))) # 128 == half transparent for cnt in range(8): gc.Scale(1.08, 1.08) # increase scale by 8% - gc.Translate(5,5) + gc.Translate(5,5) gc.DrawPath(path) @@ -151,12 +151,12 @@ class TestPanel(wx.Panel): # draw our path again, rotating it about the central point, # and changing colors as we go for angle in range(0, 360, 30): - gc.PushState() # save this new current state so we can + gc.PushState() # save this new current state so we can # pop back to it at the end of the loop r, g, b = [int(c * 255) for c in colorsys.hsv_to_rgb(float(angle)/360, 1, 1)] gc.SetBrush(wx.Brush(wx.Colour(r, g, b, 64))) gc.SetPen(wx.Pen(wx.Colour(r, g, b, 128))) - + # use translate to artfully reposition each drawn path gc.Translate(1.5 * BASE2 * cos(radians(angle)), 1.5 * BASE2 * sin(radians(angle))) @@ -172,12 +172,12 @@ class TestPanel(wx.Panel): bmp = wx.Bitmap(opj('bitmaps/toucan.png')) bsz = bmp.GetSize() gc.DrawBitmap(bmp, - #-bsz.width, + #-bsz.width, #-bsz.height/2, - -bsz.width/2.5, + -bsz.width/2.5, -bsz.height/2.5, - + bsz.width, bsz.height) diff --git a/demo/GraphicsGradient.py b/demo/GraphicsGradient.py index f53acf67..f452de34 100644 --- a/demo/GraphicsGradient.py +++ b/demo/GraphicsGradient.py @@ -21,8 +21,8 @@ class GradientPanel(wx.Panel): # create a simple default brush we can use until a gradient # brush is given to us - ctx = g.GraphicsContext.CreateMeasuringContext() - self.brush = ctx.CreateBrush(wx.Brush('white')) + ctx = g.GraphicsContext.Create() + self.brush = wx.WHITE_BRUSH def DrawWithBrush(self, brush): self.brush = brush @@ -37,7 +37,6 @@ class GradientPanel(wx.Panel): gc.DrawRectangle(0,0,w,h) - class GradientStopPanel(wx.Panel): """ Contains the controls for editing each gradient stop. (Colour, @@ -49,13 +48,13 @@ class GradientStopPanel(wx.Panel): # make some widgets self.pos = wx.SpinCtrlDouble(self, value='%2f' % posVal, size=(65,-1), min=0.0, max=1.0, initial=posVal, inc=0.01) - self.pos.SetToolTipString( + self.pos.SetToolTip( "A value between 0 and 1 representing the distance between (x1,y1) " "and (x2,y2) for this gradient stop.") - self.colour = wx.ColourPickerCtrl(self, col=colour) - self.colour.SetToolTipString("The colour for this gradient stop") + self.colour = wx.ColourPickerCtrl(self, colour=colour) + self.colour.SetToolTip("The colour for this gradient stop") self.minusBtn = wx.Button(self, -1, " - ", style=wx.BU_EXACTFIT) - self.minusBtn.SetToolTipString("Remove this gradient stop") + self.minusBtn.SetToolTip("Remove this gradient stop") # put them in a sizer sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -230,7 +229,7 @@ class TestPanel(wx.Panel): s.colour.GetColour(), s.pos.GetValue()) gstops.Add(gs) - ctx = g.GraphicsContext.CreateMeasuringContext() + ctx = g.GraphicsContext.Create() brush = ctx.CreateLinearGradientBrush(x1,y1, x2,y2, gstops) self.gpanel.DrawWithBrush(brush) diff --git a/demo/GridBagSizer.py b/demo/GridBagSizer.py index 9ea8df74..7fa2867b 100644 --- a/demo/GridBagSizer.py +++ b/demo/GridBagSizer.py @@ -68,10 +68,10 @@ class TestFrame(wx.Frame): gbs.AddGrowableCol(2) box = wx.BoxSizer() - box.Add(gbs, 1, wx.ALL|wx.EXPAND, 10) + box.Add(gbs, 0, wx.ALL, 10) - p.SetSizer(box) - self.SetClientSize(p.GetBestSize()) + p.SetSizerAndFit(box) + self.SetClientSize(p.GetSize()) def OnHideButton(self, evt): diff --git a/demo/GridCustEditor.py b/demo/GridCustEditor.py index 22d6e5bc..7b23439c 100644 --- a/demo/GridCustEditor.py +++ b/demo/GridCustEditor.py @@ -5,7 +5,7 @@ import wx import wx.grid as gridlib #--------------------------------------------------------------------------- -class MyCellEditor(gridlib.PyGridCellEditor): +class MyCellEditor(gridlib.GridCellEditor): """ This is a sample GridCellEditor that shows you how to make your own custom grid editors. All the methods that can be overridden are shown here. The @@ -15,7 +15,7 @@ class MyCellEditor(gridlib.PyGridCellEditor): def __init__(self, log): self.log = log self.log.write("MyCellEditor ctor\n") - gridlib.PyGridCellEditor.__init__(self) + gridlib.GridCellEditor.__init__(self) def Create(self, parent, id, evtHandler): @@ -39,7 +39,7 @@ class MyCellEditor(gridlib.PyGridCellEditor): PaintBackground and do something meaningful there. """ self.log.write("MyCellEditor: SetSize %s\n" % rect) - self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2, + self._tc.SetSize(rect.x, rect.y, rect.width+2, rect.height+2, wx.SIZE_ALLOW_MINUS_ONE) @@ -93,7 +93,7 @@ class MyCellEditor(gridlib.PyGridCellEditor): return val else: return None - + def ApplyEdit(self, row, col, grid): """ @@ -108,7 +108,7 @@ class MyCellEditor(gridlib.PyGridCellEditor): self.startValue = '' self._tc.SetValue('') - + def Reset(self): """ @@ -144,8 +144,8 @@ class MyCellEditor(gridlib.PyGridCellEditor): self.log.write("MyCellEditor: StartingKey %d\n" % evt.GetKeyCode()) key = evt.GetKeyCode() ch = None - if key in [ wx.WXK_NUMPAD0, wx.WXK_NUMPAD1, wx.WXK_NUMPAD2, wx.WXK_NUMPAD3, - wx.WXK_NUMPAD4, wx.WXK_NUMPAD5, wx.WXK_NUMPAD6, wx.WXK_NUMPAD7, + if key in [ wx.WXK_NUMPAD0, wx.WXK_NUMPAD1, wx.WXK_NUMPAD2, wx.WXK_NUMPAD3, + wx.WXK_NUMPAD4, wx.WXK_NUMPAD5, wx.WXK_NUMPAD6, wx.WXK_NUMPAD7, wx.WXK_NUMPAD8, wx.WXK_NUMPAD9 ]: diff --git a/demo/GridSimple.py b/demo/GridSimple.py index 9939748a..77e92c98 100644 --- a/demo/GridSimple.py +++ b/demo/GridSimple.py @@ -94,7 +94,7 @@ class SimpleGrid(gridlib.Grid): ##, mixins.GridAutoEditMixin): self.Bind(gridlib.EVT_GRID_COL_SIZE, self.OnColSize) self.Bind(gridlib.EVT_GRID_RANGE_SELECT, self.OnRangeSelect) - self.Bind(gridlib.EVT_GRID_CELL_CHANGE, self.OnCellChange) + self.Bind(gridlib.EVT_GRID_CELL_CHANGED, self.OnCellChange) self.Bind(gridlib.EVT_GRID_SELECT_CELL, self.OnSelectCell) self.Bind(gridlib.EVT_GRID_EDITOR_SHOWN, self.OnEditorShown) diff --git a/demo/GridStdEdRend.py b/demo/GridStdEdRend.py index 6a89c3e1..808f908b 100644 --- a/demo/GridStdEdRend.py +++ b/demo/GridStdEdRend.py @@ -6,15 +6,15 @@ import wx.grid as gridlib #--------------------------------------------------------------------------- -class MyCustomRenderer(gridlib.PyGridCellRenderer): +class MyCustomRenderer(gridlib.GridCellRenderer): def __init__(self): - gridlib.PyGridCellRenderer.__init__(self) + gridlib.GridCellRenderer.__init__(self) def Draw(self, grid, attr, dc, rect, row, col, isSelected): dc.SetBackgroundMode(wx.SOLID) dc.SetBrush(wx.Brush(wx.BLACK, wx.SOLID)) dc.SetPen(wx.TRANSPARENT_PEN) - dc.DrawRectangleRect(rect) + dc.DrawRectangle(rect) dc.SetBackgroundMode(wx.TRANSPARENT) dc.SetFont(attr.GetFont()) diff --git a/demo/Grid_MegaExample.py b/demo/Grid_MegaExample.py index 54c02e3a..418976a5 100644 --- a/demo/Grid_MegaExample.py +++ b/demo/Grid_MegaExample.py @@ -6,7 +6,7 @@ import images #--------------------------------------------------------------------------- -class MegaTable(Grid.PyGridTableBase): +class MegaTable(Grid.GridTableBase): """ A custom wx.Grid Table using user supplied data """ @@ -17,7 +17,7 @@ class MegaTable(Grid.PyGridTableBase): colname """ # The base class must be initialized *first* - Grid.PyGridTableBase.__init__(self) + Grid.GridTableBase.__init__(self) self.data = data self.colnames = colnames self.plugins = plugins or {} @@ -187,14 +187,14 @@ class MegaTable(Grid.PyGridTableBase): # -------------------------------------------------------------------- # Sample wx.Grid renderers -class MegaImageRenderer(Grid.PyGridCellRenderer): +class MegaImageRenderer(Grid.GridCellRenderer): def __init__(self, table): """ Image Renderer Test. This just places an image in a cell based on the row index. There are N choices and the choice is made by choice[row%N] """ - Grid.PyGridCellRenderer.__init__(self) + Grid.GridCellRenderer.__init__(self) self.table = table self._choices = [images.Smiles.GetBitmap, images.Mondrian.GetBitmap, @@ -236,10 +236,10 @@ class MegaImageRenderer(Grid.PyGridCellRenderer): 0, 0, wx.COPY, True) -class MegaFontRenderer(Grid.PyGridCellRenderer): +class MegaFontRenderer(Grid.GridCellRenderer): def __init__(self, table, color="blue", font="ARIAL", fontsize=8): """Render data in the specified color and font and fontsize""" - Grid.PyGridCellRenderer.__init__(self) + Grid.GridCellRenderer.__init__(self) self.table = table self.color = color self.font = wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, font) @@ -257,7 +257,7 @@ class MegaFontRenderer(Grid.PyGridCellRenderer): # clear the background dc.SetBackgroundMode(wx.SOLID) - + if isSelected: dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID)) dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID)) @@ -288,7 +288,7 @@ class MegaFontRenderer(Grid.PyGridCellRenderer): # when the text is larger than the grid cell width, height = dc.GetTextExtent(text) - + if width > rect.width-2: width, height = dc.GetTextExtent("...") x = rect.x+1 + rect.width-2 - width diff --git a/demo/HTML2_WebView.py b/demo/HTML2_WebView.py index e57376a8..72a56c16 100644 --- a/demo/HTML2_WebView.py +++ b/demo/HTML2_WebView.py @@ -17,8 +17,8 @@ class TestPanel(wx.Panel): sizer = wx.BoxSizer(wx.VERTICAL) btnSizer = wx.BoxSizer(wx.HORIZONTAL) self.wv = webview.WebView.New(self) - self.Bind(webview.EVT_WEB_VIEW_NAVIGATING, self.OnWebViewNavigating, self.wv) - self.Bind(webview.EVT_WEB_VIEW_LOADED, self.OnWebViewLoaded, self.wv) + self.Bind(webview.EVT_WEBVIEW_NAVIGATING, self.OnWebViewNavigating, self.wv) + self.Bind(webview.EVT_WEBVIEW_LOADED, self.OnWebViewLoaded, self.wv) btn = wx.Button(self, -1, "Open", style=wx.BU_EXACTFIT) diff --git a/demo/HtmlWindow.py b/demo/HtmlWindow.py index ec583b6b..632a9f2c 100644 --- a/demo/HtmlWindow.py +++ b/demo/HtmlWindow.py @@ -69,7 +69,7 @@ class TestHtmlPanel(wx.Panel): if frame: self.titleBase = frame.GetTitle() - html.HtmlWindow_AddFilter(MyHtmlFilter(log)) + html.HtmlWindow.AddFilter(MyHtmlFilter(log)) self.html = MyHtmlWindow(self, -1, log) self.html.SetRelatedFrame(frame, self.titleBase + " -- %s") @@ -132,10 +132,10 @@ class TestHtmlPanel(wx.Panel): def OnLoadFile(self, event): - dlg = wx.FileDialog(self, style=wx.OPEN, + dlg = wx.FileDialog(self, style=wx.FD_OPEN, wildcard='HTML Files|*.htm;*.html', ) - if dlg.ShowModal(): + if dlg.ShowModal() == wx.OK: path = dlg.GetPath() self.html.LoadPage(path) @@ -145,7 +145,7 @@ class TestHtmlPanel(wx.Panel): def OnLoadURL(self, event): dlg = wx.TextEntryDialog(self, "Enter a URL") - if dlg.ShowModal(): + if dlg.ShowModal() == wx.OK: url = dlg.GetValue() self.html.LoadPage(url) diff --git a/demo/I18N.py b/demo/I18N.py index e35f483a..15063047 100644 --- a/demo/I18N.py +++ b/demo/I18N.py @@ -24,20 +24,20 @@ exampleStrings = [ ] -[wxID_LANGUAGESELECTPANEL, wxID_LANGUAGESELECTPANELENGLISHBASECH, - wxID_LANGUAGESELECTPANELLANGCTRLCONTAINER, - wxID_LANGUAGESELECTPANELLANGFILTERRB, wxID_LANGUAGESELECTPANELSTATICLINE1, - wxID_LANGUAGESELECTPANELSTATICTEXT1, wxID_LANGUAGESELECTPANELSTATICTEXT2, - wxID_LANGUAGESELECTPANELSTATICTEXT3, wxID_LANGUAGESELECTPANELTRANSLATEDST, +[wxID_LANGUAGESELECTPANEL, wxID_LANGUAGESELECTPANELENGLISHBASECH, + wxID_LANGUAGESELECTPANELLANGCTRLCONTAINER, + wxID_LANGUAGESELECTPANELLANGFILTERRB, wxID_LANGUAGESELECTPANELSTATICLINE1, + wxID_LANGUAGESELECTPANELSTATICTEXT1, wxID_LANGUAGESELECTPANELSTATICTEXT2, + wxID_LANGUAGESELECTPANELSTATICTEXT3, wxID_LANGUAGESELECTPANELTRANSLATEDST, ] = [wx.NewId() for _init_ctrls in range(9)] class LanguageSelectPanel(wx.Panel): def _init_coll_boxSizer3_Items(self, parent): # generated method, don't edit - parent.AddWindow(self.langCtrlContainer, 1, border=0, flag=wx.GROW) - parent.AddSpacer(wx.Size(8, 8), border=0, flag=0) - parent.AddWindow(self.langFilterRB, 0, border=0, flag=0) + parent.Add(self.langCtrlContainer, 1, flag=wx.GROW, border=0) + parent.Add(wx.Size(8, 8), flag=0, border=0) + parent.Add(self.langFilterRB, 0, flag=0, border=0) def _init_coll_flexGridSizer1_Growables(self, parent): # generated method, don't edit @@ -48,18 +48,18 @@ class LanguageSelectPanel(wx.Panel): def _init_coll_boxSizer1_Items(self, parent): # generated method, don't edit - parent.AddWindow(self.staticText1, 0, border=8, flag=wx.ALL) - parent.AddSizer(self.boxSizer3, 1, border=8, flag=wx.ALL | wx.GROW) - parent.AddSizer(self.boxSizer2, 0, border=8, flag=wx.GROW | wx.ALL) + parent.Add(self.staticText1, 0, border=8, flag=wx.ALL) + parent.Add(self.boxSizer3, 1, flag=wx.ALL | wx.GROW, border=8) + parent.Add(self.boxSizer2, 0, flag=wx.GROW | wx.ALL, border=8) def _init_coll_boxSizer2_Items(self, parent): # generated method, don't edit - parent.AddWindow(self.staticText2, 0, border=8, flag=wx.ALL) - parent.AddWindow(self.englishBaseCh, 0, border=8, flag=wx.GROW | wx.ALL) - parent.AddWindow(self.staticLine1, 0, border=8, flag=wx.GROW | wx.ALL) - parent.AddWindow(self.staticText3, 0, border=8, flag=wx.ALL) - parent.AddWindow(self.translatedST, 0, border=8, flag=wx.GROW | wx.ALL) + parent.Add(self.staticText2, 0, flag=wx.ALL, border=8) + parent.Add(self.englishBaseCh, 0, flag=wx.GROW | wx.ALL, border=8) + parent.Add(self.staticLine1, 0, flag=wx.GROW | wx.ALL, border=8) + parent.Add(self.staticText3, 0, flag=wx.ALL, border=8) + parent.Add(self.translatedST, 0, flag=wx.GROW | wx.ALL, border=8) def _init_sizers(self): # generated method, don't edit @@ -81,9 +81,9 @@ class LanguageSelectPanel(wx.Panel): def _init_ctrls(self, prnt): # generated method, don't edit wx.Panel.__init__(self, id=wxID_LANGUAGESELECTPANEL, - name='LanguageSelectPanel', parent=prnt, + name='LanguageSelectPanel', parent=prnt, style=wx.RESIZE_BORDER | wx.DEFAULT_DIALOG_STYLE) - + self.staticText1 = wx.StaticText(id=wxID_LANGUAGESELECTPANELSTATICTEXT1, label='Choose a language that will be used for example translation.', name='staticText1', parent=self, style=0) @@ -126,14 +126,14 @@ class LanguageSelectPanel(wx.Panel): def __init__(self, parent, log): self.choices = [] self.choices = exampleStrings - + self._init_ctrls(parent) self.log = log lang = wx.LANGUAGE_DEFAULT filter = 'demo' - langs = (wx.LANGUAGE_AFRIKAANS, wx.LANGUAGE_ENGLISH, wx.LANGUAGE_DEFAULT, + langs = (wx.LANGUAGE_AFRIKAANS, wx.LANGUAGE_ENGLISH, wx.LANGUAGE_DEFAULT, wx.LANGUAGE_SPANISH, wx.LANGUAGE_GERMAN, wx.LANGUAGE_ITALIAN, wx.LANGUAGE_FRENCH) @@ -144,23 +144,23 @@ class LanguageSelectPanel(wx.Panel): wx.Locale.AddCatalogLookupPathPrefix(opj('data/locale')) self.updateLanguage(wx.LANGUAGE_DEFAULT) - - self.filterMap = {'demo': langlistctrl.LC_ONLY, - 'available': langlistctrl.LC_AVAILABLE, + + self.filterMap = {'demo': langlistctrl.LC_ONLY, + 'available': langlistctrl.LC_AVAILABLE, 'all': langlistctrl.LC_ALL} - - self.filterIdxMap = {0: 'demo', - 1: 'available', + + self.filterIdxMap = {0: 'demo', + 1: 'available', 2: 'all'} self.langs = langs - self.langCtrl = langlistctrl.LanguageListCtrl(self.langCtrlContainer, -1, + self.langCtrl = langlistctrl.LanguageListCtrl(self.langCtrlContainer, -1, filter=self.filterMap[filter], only=langs, select=lang) - + self.langCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnLangSelectAndTranslate) self.langCtrl.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnClearTranslatedText) - + self.OnLangCtrlContainerSize() - + self.englishBaseCh.Select(0) self.OnLangSelectAndTranslate() @@ -174,7 +174,7 @@ class LanguageSelectPanel(wx.Panel): if self.locale: assert sys.getrefcount(self.locale) <= 2 del self.locale - + # create a locale object for this language self.locale = wx.Locale(lang) if self.locale.IsOk(): @@ -196,22 +196,22 @@ class LanguageSelectPanel(wx.Panel): def OnLangSelectAndTranslate(self, event=None): lang = self.langCtrl.GetLanguage() - + if lang is not None: # set to the selected language self.updateLanguage(lang) self.translateExample() - + # set back to default self.updateLanguage(wx.LANGUAGE_DEFAULT) def OnClearTranslatedText(self, event): - self.translatedST.SetLabel('') + self.translatedST.SetLabel('') def runTest(frame, nb, log): - win = LanguageSelectPanel(nb, log) + win = LanguageSelectPanel(nb, log) return win #------------------------------------------------------------------------------- @@ -221,13 +221,13 @@ overview = """

This demo demonstrates how to setup and use the wx.Locale object to translate text.

-It also shows the langlistctrl.LanguageListCtrl that can be used to display +It also shows the langlistctrl.LanguageListCtrl that can be used to display languages with their associated countries flags, e.g. for setting the language in your application. """ - + if __name__ == '__main__': import sys,os import run diff --git a/demo/Image.py b/demo/Image.py index 7b1cdb7c..b8320417 100644 --- a/demo/Image.py +++ b/demo/Image.py @@ -55,7 +55,9 @@ a file in a variety of formats, and is extensible to new formats via image format handlers. Functions are available to set and get image bits, so it can be used for basic image manipulation. -

The following image handlers are available. +

The following image handlers are available. wxBMPHandler is always installed +by default. To use other image formats, install the appropriate handler or use +wx.InitAllImageHandlers().

diff --git a/demo/ImageFromStream.py b/demo/ImageFromStream.py index 15e1e399..0e1cc7b4 100644 --- a/demo/ImageFromStream.py +++ b/demo/ImageFromStream.py @@ -14,7 +14,7 @@ class TestPanel(wx.Panel): data = open(opj('bitmaps/image.png'), "rb").read() stream = cStringIO.StringIO(data) - bmp = wx.BitmapFromImage( wx.ImageFromStream( stream )) + bmp = wx.Bitmap(wx.Image(stream)) wx.StaticText( self, -1, "This image was loaded from a Python file-like object:", diff --git a/demo/Img2PyArtProvider.py b/demo/Img2PyArtProvider.py index 206979f0..bd2f55c7 100644 --- a/demo/Img2PyArtProvider.py +++ b/demo/Img2PyArtProvider.py @@ -29,7 +29,7 @@ class TestPanel(wx.Panel): box.Add(ch, 0, wx.ALIGN_CENTER_VERTICAL) box.Add((50,10)) - bmp = wx.EmptyBitmap(32,22) + bmp = wx.Bitmap(32,22) self.bmpFlag = wx.StaticBitmap(self, -1, bmp) box.Add(self.bmpFlag, 0, wx.ALIGN_CENTER_VERTICAL) @@ -53,8 +53,8 @@ class TestPanel(wx.Panel): def getArt(self): bmp = wx.ArtProvider.GetBitmap('wx.ART_'+self.country, wx.ART_OTHER, (32,22)) - if not bmp.Ok(): - bmp = wx.EmptyBitmap(32,22) + if not bmp.IsOk(): + bmp = wx.Bitmap(32,22) self.clearBmp(bmp) self.bmpFlag.SetBitmap(bmp) diff --git a/demo/ItemsPicker.py b/demo/ItemsPicker.py index c7a27b41..9f3b8cff 100644 --- a/demo/ItemsPicker.py +++ b/demo/ItemsPicker.py @@ -24,7 +24,7 @@ class TestPanel(wx.Panel): b.Bind(wx.EVT_BUTTON,self.Go) sizer.Add(b,0,wx.ALL,10) self.SetSizer(sizer) - + def Go(self,e): style = 0 if self.sortChoices.GetValue(): @@ -35,17 +35,17 @@ class TestPanel(wx.Panel): style |= IP_REMOVE_FROM_CHOICES d = ItemsPickerDialog(self, style, self.log) d.ShowModal() - - + + class ItemsPickerDialog(wx.Dialog): def __init__(self,parent, style, log): wx.Dialog.__init__(self,parent) self.log = log - sizer =wx.BoxSizer(wx.VERTICAL) + sizer = wx.BoxSizer(wx.VERTICAL) b = wx.Button(self, -1, "Add Item") b.Bind(wx.EVT_BUTTON, self.OnAdd) sizer.Add(b, 0, wx.ALL, 5) - self.ip = ItemsPicker(self,-1, + self.ip = ItemsPicker(self,-1, ['ThisIsItem3','ThisIsItem2','ThisIsItem1'], 'Stuff:', 'Selected stuff:',ipStyle = style) self.ip.Bind(EVT_IP_SELECTION_CHANGED, self.OnSelectionChange) @@ -54,13 +54,13 @@ class ItemsPickerDialog(wx.Dialog): self.SetSizer(sizer) self.itemCount = 3 self.Fit() - + def OnAdd(self,e): items = self.ip.GetItems() self.itemCount += 1 newItem = "item%d" % self.itemCount self.ip.SetItems(items + [newItem]) - + def OnSelectionChange(self, e): self.log.write("EVT_IP_SELECTION_CHANGED %s\n" % \ ",".join(e.GetItems())) @@ -76,14 +76,14 @@ def runTest(frame, nb, log): overview = """ -

ItemsPicker

- +

ItemsPicker

+ ItemsPicker is a widget that allows the user to choose a set of picked items out of a given list """ - + if __name__ == '__main__': import sys,os diff --git a/demo/Joystick.py b/demo/Joystick.py index f26d7e1a..26696289 100644 --- a/demo/Joystick.py +++ b/demo/Joystick.py @@ -6,7 +6,7 @@ # .wdr-derived demo # # Created: 02-Jan-2004 -# RCS-ID: $Id$ +# RCS-ID: $Id: Joystick.py 71447 2012-05-17 02:41:08Z RD $ # Copyright: # Licence: wxWindows license #---------------------------------------------------------------------------- @@ -14,6 +14,7 @@ import math import wx +import wx.adv haveJoystick = True if wx.Platform == "__WXMAC__": @@ -45,41 +46,38 @@ class JoyGauge(wx.Panel): self.stick = stick size = (100,100) - + wx.Panel.__init__(self, parent, -1, size=size) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) - self.buffer = wx.EmptyBitmap(*size) + self.buffer = wx.Bitmap(*size) dc = wx.BufferedDC(None, self.buffer) self.DrawFace(dc) self.DrawJoystick(dc) - + def OnSize(self, event): # The face Bitmap init is done here, to make sure the buffer is always # the same size as the Window w, h = self.GetClientSize() - self.buffer = wx.EmptyBitmap(w,h) + self.buffer = wx.Bitmap(w,h) dc = wx.BufferedDC(wx.ClientDC(self), self.buffer) self.DrawFace(dc) self.DrawJoystick(dc) - def DrawFace(self, dc): dc.SetBackground(wx.Brush(self.GetBackgroundColour())) dc.Clear() - def OnPaint(self, evt): # When dc is destroyed it will blit self.buffer to the window, # since no other drawing is needed we'll just return and let it # do it's thing dc = wx.BufferedPaintDC(self, self.buffer) - def DrawJoystick(self, dc): # draw the guage as a maxed square in the center of this window. w, h = self.GetClientSize() @@ -94,7 +92,7 @@ class JoyGauge(wx.Panel): dc.SetClippingRegion(xorigin, yorigin, edgeSize, edgeSize) # Optimize drawing a bit (for Win) - dc.BeginDrawing() + # dc.BeginDrawing() dc.SetBrush(wx.Brush(wx.Colour(251, 252, 237))) dc.DrawRectangle(xorigin, yorigin, edgeSize, edgeSize) @@ -143,8 +141,7 @@ class JoyGauge(wx.Panel): dc.CrossHair(x, y) # Turn off drawing optimization - dc.EndDrawing() - + # dc.EndDrawing() def Update(self): dc = wx.BufferedDC(wx.ClientDC(self), self.buffer) @@ -201,7 +198,7 @@ class POVGauge(wx.Panel): self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) - self.buffer = wx.EmptyBitmap(*self.size) + self.buffer = wx.Bitmap(*self.size) dc = wx.BufferedDC(None, self.buffer) self.DrawFace(dc) self.DrawPOV(dc) @@ -212,24 +209,21 @@ class POVGauge(wx.Panel): w, h = self.GetClientSize() s = min(w, h) self.size = (s, s) - self.buffer = wx.EmptyBitmap(w,h) + self.buffer = wx.Bitmap(w,h) dc = wx.BufferedDC(wx.ClientDC(self), self.buffer) self.DrawFace(dc) self.DrawPOV(dc) - def DrawFace(self, dc): dc.SetBackground(wx.Brush(self.GetBackgroundColour())) dc.Clear() - def OnPaint(self, evt): # When dc is destroyed it will blit self.buffer to the window, # since no other drawing is needed we'll just return and let it # do it's thing dc = wx.BufferedPaintDC(self, self.buffer) - def DrawPOV(self, dc): # draw the guage as a maxed circle in the center of this window. w, h = self.GetClientSize() @@ -241,7 +235,7 @@ class POVGauge(wx.Panel): ycenter = yorigin + diameter / 2 # Optimize drawing a bit (for Win) - dc.BeginDrawing() + # dc.BeginDrawing() # our 'raster'. dc.SetBrush(wx.Brush(wx.WHITE)) @@ -297,15 +291,13 @@ class POVGauge(wx.Panel): dc.DrawCircle(nx, ny, 8) # Turn off drawing optimization - dc.EndDrawing() - + # dc.EndDrawing() def Update(self): dc = wx.BufferedDC(wx.ClientDC(self), self.buffer) self.DrawFace(dc) self.DrawPOV(dc) - def Calibrate(self): s = self.stick self.avail = s.HasPOV() @@ -327,7 +319,7 @@ class POVStatus(wx.Panel): sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add((20,20)) - + self.avail = wx.CheckBox(self, -1, "Available") sizer.Add(self.avail, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 2) @@ -364,7 +356,7 @@ class POVPanel(wx.Panel): gsizer = wx.BoxSizer(wx.VERTICAL) sizer.Add((25,25)) - + fn = parent.GetFont() fn.SetPointSize(fn.GetPointSize() + 3) fn.SetWeight(wx.BOLD) @@ -372,11 +364,11 @@ class POVPanel(wx.Panel): t = wx.StaticText(self, -1, "POV Control", style = wx.ALIGN_CENTER) t.SetFont(fn) gsizer.Add(t, 0, wx.ALL | wx.EXPAND, 1) - + self.display = POVGauge(self, stick) gsizer.Add(self.display, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1) sizer.Add(gsizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1) - + self.status = POVStatus(self, stick) sizer.Add(self.status, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1) @@ -406,14 +398,14 @@ class LED(wx.Panel): fn.SetPointSize(fn.GetPointSize() - 1) fn.SetWeight(wx.BOLD) self.fn = fn - + wx.Panel.__init__(self, parent, -1, size=self.size) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) - self.buffer = wx.EmptyBitmap(*self.size) + self.buffer = wx.Bitmap(*self.size) dc = wx.BufferedDC(None, self.buffer) self.DrawFace(dc) self.DrawLED(dc) @@ -424,7 +416,7 @@ class LED(wx.Panel): w, h = self.GetClientSize() s = min(w, h) self.size = (s, s) - self.buffer = wx.EmptyBitmap(*self.size) + self.buffer = wx.Bitmap(*self.size) dc = wx.BufferedDC(wx.ClientDC(self), self.buffer) self.DrawFace(dc) self.DrawLED(dc) @@ -454,7 +446,7 @@ class LED(wx.Panel): yorigin = center - (bh / 2) # Optimize drawing a bit (for Win) - dc.BeginDrawing() + # dc.BeginDrawing() # our 'raster'. if self.state == 0: @@ -488,7 +480,8 @@ class LED(wx.Panel): dc.DrawText(txt, tx, ty) # Turn off drawing optimization - dc.EndDrawing() + # dc.EndDrawing() + # dc.EndDrawing() def Update(self): @@ -815,9 +808,9 @@ class Axis(wx.Panel): if min < 0: max += abs(min) val += abs(min) - min = 0 + min = 0 range = float(max - min) - + # # The relative value is used by the derived wx.Gauge since it is a # positive-only control. @@ -905,7 +898,7 @@ class JoystickDemoPanel(wx.Panel): # Try to grab the control. If we get it, capture the stick. # Otherwise, throw up an exception message and play stupid. try: - self.stick = wx.Joystick() + self.stick = wx.adv.Joystick() self.stick.SetCapture(self) # Calibrate our controls wx.CallAfter(self.Calibrate) @@ -924,10 +917,10 @@ class JoystickDemoPanel(wx.Panel): self.joy = JoyPanel(self, self.stick) sizer.Add(self.joy, (1, 0), (1, 1), wx.ALL | wx.GROW, 2) - + self.pov = POVPanel(self, self.stick) sizer.Add(self.pov, (1, 1), (1, 2), wx.ALL | wx.GROW, 2) - + self.axes = AxisPanel(self, self.stick) sizer.Add(self.axes, (2, 0), (1, 3), wx.ALL | wx.GROW, 2) @@ -968,7 +961,7 @@ class JoystickDemoPanel(wx.Panel): if self.stick: self.stick.ReleaseCapture() self.stick = None - + #---------------------------------------------------------------------------- def runTest(frame, nb, log): @@ -980,7 +973,7 @@ def runTest(frame, nb, log): win = MessagePanel(nb, 'wx.Joystick is not available on this platform.', 'Sorry', wx.ICON_WARNING) return win - + #---------------------------------------------------------------------------- @@ -1009,13 +1002,13 @@ a regular basis.

Data types

Data from the joystick comes in two flavors: that which defines the boundaries, and that -which defines the current state of the stick. Thus, we have Get*Max() and Get*Min() +which defines the current state of the stick. Thus, we have Get*Max() and Get*Min() methods for all axes, the max number of axes, the max number of buttons, and so on. In general, this data can be read once and stored to speed computation up.

Analog Input

-Analog input (the axes) is delivered as a whole, positive number. If you need to know +Analog input (the axes) is delivered as a whole, positive number. If you need to know if the axis is at zero (centered) or not, you will first have to calculate that center based on the max and min values. The demo shows a bar graph for each axis expressed in native numerical format, plus a 'centered' X-Y axis compass showing the relationship @@ -1031,29 +1024,29 @@ Button state is retrieved as one int that contains each button state mapped to a You get the state of a button by AND-ing its bit against the returned value, in the form
-     # assume buttonState is what the stick returned, and buttonBit 
+     # assume buttonState is what the stick returned, and buttonBit
      # is the bit you want to examine
-     
+
      if (buttonState & ( 1 << buttonBit )) :
          # button pressed, do something with it
 
-

The problem here is that some OSs return a 32-bit value for up to 32 buttons -(imagine that stick!). Python V2.3 will generate an exception for bit +

The problem here is that some OSs return a 32-bit value for up to 32 buttons +(imagine that stick!). Python V2.3 will generate an exception for bit values over 30. For that reason, this demo is limited to 16 buttons.

Note that more than one button can be pressed at a time, so be sure to check all of them! - +

POV Input

POV hats come in two flavors: four-way, and continuous. four-way POVs are restricted to the cardinal points of the compass; continuous, or CTS POV hats can deliver input in .01 degree increments, theoreticaly. The data is returned as a whole number; the last -two digits are considered to be to the right of the decimal point, so in order to -use this information, you need to divide by 100 right off the bat. +two digits are considered to be to the right of the decimal point, so in order to +use this information, you need to divide by 100 right off the bat. -

Different methods are provided to retrieve the POV data for a CTS hat +

Different methods are provided to retrieve the POV data for a CTS hat versus a four-way hat.

Caveats

@@ -1072,9 +1065,9 @@ rely on wx.JoystickEvents to tell you when something has changed, necessarilly.

Fortunately, there is an easy workaround. In the top level frame, create a wx.Timer that will poll the stick at a set interval. Of course, if you do this, you might as well forgo catching wxEVT_JOYSTICK_* events at all and rely on the timer to do the -polling. +polling. -

Ideally, the timer should be a one-shot; after it fires, collect and process data as +

Ideally, the timer should be a one-shot; after it fires, collect and process data as needed, then re-start the timer, possibly using wx.CallAfter(). diff --git a/demo/KeyEvents.py b/demo/KeyEvents.py index 90277cc0..603cc528 100644 --- a/demo/KeyEvents.py +++ b/demo/KeyEvents.py @@ -141,7 +141,7 @@ if 'wxMac' in wx.PlatformInfo: else: keyMap[wx.WXK_COMMAND] = "WXK_COMMAND" keyMap[wx.WXK_CONTROL] = "WXK_CONTROL" - + #---------------------------------------------------------------------- @@ -230,14 +230,14 @@ class KeySink(wx.Window): class KeyLog(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): colHeaders = [ "Event Type", - "Key Name", - "Key Code", + "Key Name", + "Key Code", "Modifiers", "Unicode", "UniChr", "RawKeyCode", "RawKeyFlags", - ] + ] def __init__(self, parent): wx.ListCtrl.__init__(self, parent, -1, @@ -272,8 +272,9 @@ class KeyLog(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): UniChr = '' if "unicode" in wx.PlatformInfo: - UniChr = "\"" + unichr(evt.GetUnicodeKey()) + "\"" - + # UniChr = "\"" + unichr(evt.GetUnicodeKey()) + "\"" + UniChr = "\"" + unichr(keycode) + "\"" + modifiers = "" for mod, ch in [(evt.ControlDown(), 'C'), (evt.AltDown(), 'A'), @@ -285,14 +286,15 @@ class KeyLog(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): else: modifiers += '-' - id = self.InsertStringItem(self.GetItemCount(), evType) - self.SetStringItem(id, 1, keyname) - self.SetStringItem(id, 2, str(keycode)) - self.SetStringItem(id, 3, modifiers) - self.SetStringItem(id, 4, str(evt.GetUnicodeKey())) - self.SetStringItem(id, 5, UniChr) - self.SetStringItem(id, 6, str(evt.GetRawKeyCode())) - self.SetStringItem(id, 7, str(evt.GetRawKeyFlags())) + id = self.InsertItem(self.GetItemCount(), evType) + self.SetItem(id, 1, keyname) + self.SetItem(id, 2, str(keycode)) + self.SetItem(id, 3, modifiers) + # self.SetItem(id, 4, str(evt.GetUnicodeKey())) + self.SetItem(id, 4, unicode(unichr(keycode))) + self.SetItem(id, 5, UniChr) + self.SetItem(id, 6, str(evt.GetRawKeyCode())) + self.SetItem(id, 7, str(evt.GetRawKeyFlags())) #print ( id, evType, keyname, str(keycode), modifiers, str(evt.GetRawKeyCode()), str(evt.GetRawKeyFlags())) @@ -325,8 +327,8 @@ class KeyLog(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): wx.TheClipboard.Close() else: wx.MessageBox("Unable to open the clipboard", "Error") - - + + #---------------------------------------------------------------------- @@ -342,12 +344,12 @@ class TestPanel(wx.Panel): btn = wx.Button(self, -1, "Clear", style=wx.BU_EXACTFIT) self.Bind(wx.EVT_BUTTON, self.OnClearBtn, btn) - btn.SetToolTipString( + btn.SetToolTip( "Clear the items from the log window") btn2 = wx.Button(self, -1, "Copy", style=wx.BU_EXACTFIT) self.Bind(wx.EVT_BUTTON, self.OnCopyBtn, btn2) - btn2.SetToolTipString( + btn2.SetToolTip( "Copy the contents of the log window to the clipboard") cb1 = wx.CheckBox(self, -1, "Call evt.Skip in Key* events") diff --git a/demo/LayoutConstraints.py b/demo/LayoutConstraints.py index 3484fe5d..278d2887 100644 --- a/demo/LayoutConstraints.py +++ b/demo/LayoutConstraints.py @@ -9,7 +9,7 @@ class TestLayoutConstraints(wx.Panel): self.SetAutoLayout(True) self.Bind(wx.EVT_BUTTON, self.OnButton, id=100) - self.SetBackgroundColour(wx.NamedColour("MEDIUM ORCHID")) + self.SetBackgroundColour(wx.Colour("MEDIUM ORCHID")) self.panelA = wx.Window(self, -1, style=wx.SIMPLE_BORDER) self.panelA.SetBackgroundColour(wx.BLUE) diff --git a/demo/ListBox.py b/demo/ListBox.py index 0e1816a8..2f1273c3 100644 --- a/demo/ListBox.py +++ b/demo/ListBox.py @@ -34,7 +34,6 @@ class FindPrefixListBox(wx.ListBox): self.log.WriteText('Prefix %s is not found.\n' % prefix) return -1 - def OnKey(self, evt): key = evt.GetKeyCode() @@ -101,18 +100,18 @@ class TestListBox(wx.Panel): def EvtListBox(self, event): - self.log.WriteText('EvtListBox: %s, %s, %s, %s\n' % + self.log.WriteText('EvtListBox: %s, %s, %s\n' % (event.GetString(), event.IsSelection(), - event.GetSelection(), - event.GetClientData())) + event.GetSelection() + # event.GetClientData() + )) lb = event.GetEventObject() - data = lb.GetClientData(lb.GetSelection()) - - if data is not None: - self.log.WriteText('\tdata: %s\n' % data) + # data = lb.GetClientData(lb.GetSelection()) + # if data is not None: + # self.log.WriteText('\tdata: %s\n' % data) def EvtListBoxDClick(self, event): self.log.WriteText('EvtListBoxDClick: %s\n' % self.lb1.GetSelection()) @@ -142,7 +141,6 @@ def runTest(frame, nb, log): - overview = """ A listbox is used to select one or more of a list of strings. The strings are displayed in a scrolling box, with the diff --git a/demo/ListCtrl.py b/demo/ListCtrl.py index 7ad06c1d..75dd4423 100644 --- a/demo/ListCtrl.py +++ b/demo/ListCtrl.py @@ -5,7 +5,7 @@ # Author: Robin Dunn & Gary Dumer # # Created: -# RCS-ID: $Id$ +# RCS-ID: $Id: ListCtrl.py 70188 2011-12-29 23:25:41Z RD $ # Copyright: (c) 1998 by Total Control Software # Licence: wxWindows license #---------------------------------------------------------------------------- @@ -90,17 +90,17 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): self.log = log tID = wx.NewId() - + sizer = wx.BoxSizer(wx.VERTICAL) - + if wx.Platform == "__WXMAC__" and \ hasattr(wx.GetApp().GetTopWindow(), "LoadDemo"): self.useNative = wx.CheckBox(self, -1, "Use native listctrl") - self.useNative.SetValue( + self.useNative.SetValue( not wx.SystemOptions.GetOptionInt("mac.listctrl.always_use_generic") ) self.Bind(wx.EVT_CHECKBOX, self.OnUseNative, self.useNative) sizer.Add(self.useNative, 0, wx.ALL | wx.ALIGN_RIGHT, 4) - + self.il = wx.ImageList(16, 16) self.idx1 = self.il.Add(images.Smiles.GetBitmap()) @@ -108,7 +108,7 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): self.sm_dn = self.il.Add(images.SmallDnArrow.GetBitmap()) self.list = TestListCtrl(self, tID, - style=wx.LC_REPORT + style=wx.LC_REPORT #| wx.BORDER_SUNKEN | wx.BORDER_NONE | wx.LC_EDIT_LABELS @@ -118,7 +118,7 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): #| wx.LC_HRULES #| wx.LC_SINGLE_SEL ) - + self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL) sizer.Add(self.list, 1, wx.EXPAND) @@ -153,7 +153,6 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): # for wxGTK self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightClick) - def OnUseNative(self, event): wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", not event.IsChecked()) wx.GetApp().GetTopWindow().LoadDemo("ListCtrl") @@ -167,25 +166,25 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): else: # but since we want images on the column header we have to do it the hard way: info = wx.ListItem() - info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT - info.m_image = -1 - info.m_format = 0 - info.m_text = "Artist" - self.list.InsertColumnInfo(0, info) + info.Mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT + info.Image = -1 + info.Align = 0 + info.Text = "Artist" + self.list.InsertColumn(0, info) - info.m_format = wx.LIST_FORMAT_RIGHT - info.m_text = "Title" - self.list.InsertColumnInfo(1, info) + info.Align = wx.LIST_FORMAT_RIGHT + info.Text = "Title" + self.list.InsertColumn(1, info) - info.m_format = 0 - info.m_text = "Genre" - self.list.InsertColumnInfo(2, info) + info.Align = 0 + info.Text = "Genre" + self.list.InsertColumn(2, info) items = musicdata.items() for key, data in items: - index = self.list.InsertImageStringItem(sys.maxint, data[0], self.idx1) - self.list.SetStringItem(index, 1, data[1]) - self.list.SetStringItem(index, 2, data[2]) + index = self.list.InsertItem(sys.maxint, data[0], self.idx1) + self.list.SetItem(index, 1, data[1]) + self.list.SetItem(index, 2, data[2]) self.list.SetItemData(index, key) self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE) @@ -205,7 +204,6 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): self.currentItem = 0 - # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py def GetListCtrl(self): return self.list @@ -214,7 +212,6 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): def GetSortImages(self): return (self.sm_dn, self.sm_up) - def OnRightDown(self, event): x = event.GetX() y = event.GetY() @@ -226,15 +223,13 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): event.Skip() - def getColumnText(self, index, col): item = self.list.GetItem(index, col) return item.GetText() - def OnItemSelected(self, event): ##print event.GetItem().GetTextColour() - self.currentItem = event.m_itemIndex + self.currentItem = event.Index self.log.WriteText("OnItemSelected: %s, %s, %s, %s\n" % (self.currentItem, self.list.GetItemText(self.currentItem), @@ -249,18 +244,16 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): event.Skip() - def OnItemDeselected(self, evt): item = evt.GetItem() - self.log.WriteText("OnItemDeselected: %d" % evt.m_itemIndex) + self.log.WriteText("OnItemDeselected: %d" % evt.Index) # Show how to reselect something we don't want deselected - if evt.m_itemIndex == 11: + if evt.Index == 11: wx.CallAfter(self.list.SetItemState, 11, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) - def OnItemActivated(self, event): - self.currentItem = event.m_itemIndex + self.currentItem = event.Index self.log.WriteText("OnItemActivated: %s\nTopItem: %s" % (self.list.GetItemText(self.currentItem), self.list.GetTopItem())) @@ -290,7 +283,6 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): #if event.GetColumn() == 0: # event.Veto() - def OnColDragging(self, event): self.log.WriteText("OnColDragging\n") @@ -335,18 +327,18 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): self.PopupMenu(menu) menu.Destroy() - def OnPopupOne(self, event): self.log.WriteText("Popup one\n") - print "FindItem:", self.list.FindItem(-1, "Roxette") - print "FindItemData:", self.list.FindItemData(-1, 11) + print("FindItem:", self.list.FindItem(-1, "Roxette")) + print("FindItemData:", self.list.FindItemData(-1, 11)) def OnPopupTwo(self, event): self.log.WriteText("Selected items:\n") index = self.list.GetFirstSelected() while index != -1: - self.log.WriteText(" %s: %s\n" % (self.list.GetItemText(index), self.getColumnText(index, 1))) + self.log.WriteText(" %s: %s\n" % (self.list.GetItemText(index), + self.getColumnText(index, 1))) index = self.list.GetNextSelected(index) def OnPopupThree(self, event): @@ -359,7 +351,9 @@ class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): def OnPopupFive(self, event): item = self.list.GetItem(self.currentItem) - print item.m_text, item.m_itemId, self.list.GetItemData(self.currentItem) + self.log.WriteText("Text:%s, Id:%s, Data:%s" %(item.Text, + item.Id, + self.list.GetItemData(self.currentItem))) def OnPopupSix(self, event): self.list.EditLabel(self.currentItem) @@ -377,12 +371,12 @@ def runTest(frame, nb, log): overview = """\ -A list control presents lists in a number of formats: list view, report view, -icon view and small icon view. In any case, elements are numbered from zero. -For all these modes (but not for virtual list controls), the items are stored +A list control presents lists in a number of formats: list view, report view, +icon view and small icon view. In any case, elements are numbered from zero. +For all these modes (but not for virtual list controls), the items are stored in the control and must be added to it using InsertItem method. -

To intercept events from a list control, use the event table macros described in +

To intercept events from a list control, use the event table macros described in wxListEvent.

Mix-ins

@@ -392,22 +386,22 @@ This example demonstrates how to use mixins. The following mixins are available. ColumnSorterMixin(numColumns) -

A mixin class that handles sorting of a wxListCtrl in REPORT mode when the column +

A mixin class that handles sorting of a wxListCtrl in REPORT mode when the column header is clicked on.

There are a few requirments needed in order for this to work genericly:

    -
  1. The combined class must have a GetListCtrl method that returns - the ListCtrl to be sorted, and the list control must exist at the time the - ColumnSorterMixin.__init__()method is called because it uses +
  2. The combined class must have a GetListCtrl method that returns + the ListCtrl to be sorted, and the list control must exist at the time the + ColumnSorterMixin.__init__()method is called because it uses GetListCtrl. -
  3. Items in the list control must have a unique data value set with +
  4. Items in the list control must have a unique data value set with list.SetItemData.
  5. The combined class must have an attribute named itemDataMap - that is a dictionary mapping the data values to a sequence of objects - representing the values in each column. These valuesare compared in + that is a dictionary mapping the data values to a sequence of objects + representing the values in each column. These valuesare compared in the column sorter to determine sort order.
@@ -424,11 +418,11 @@ set, it also sets up an event handler for EVT_LIST_COL_CLICK events
Sort the list on demand. Can also be used to set the sort column and order.
GetColumnWidths() -
Returns a list of column widths. Can be used to help restore the current +
Returns a list of column widths. Can be used to help restore the current view later.
GetSortImages() -
Returns a tuple of image list indexes the indexes in the image list for an +
Returns a tuple of image list indexes the indexes in the image list for an image to be put on the column header when sorting in descending order
GetColumnSorter() @@ -436,7 +430,7 @@ image to be put on the column header when sorting in descending order
GetSecondarySortValues(col, key1, key2)
Returns a tuple of 2 values to use for secondary sort values when the -items in the selected column match equal. The default just returns the +items in the selected column match equal. The default just returns the item data values. @@ -445,17 +439,17 @@ item data values. ListCtrlAutoWidthMixin() -

A mix-in class that automatically resizes the last column to take up the +

A mix-in class that automatically resizes the last column to take up the remaining width of the ListCtrl. -

This causes the ListCtrl to automatically take up the full width of the list, -without either a horizontal scroll bar (unless absolutely necessary) or empty +

This causes the ListCtrl to automatically take up the full width of the list, +without either a horizontal scroll bar (unless absolutely necessary) or empty space to the right of the last column.

NOTE: This only works for report-style lists. -

WARNING: If you override the EVT_SIZE event in your ListCtrl, -make sure you call event.Skip() to ensure that the mixin's _OnResize method is +

WARNING: If you override the EVT_SIZE event in your ListCtrl, +make sure you call event.Skip() to ensure that the mixin's _OnResize method is called.

This mix-in class was written by Erik Westra @@ -464,12 +458,12 @@ called.

resizeLastColumn(minWidth) -
Resize the last column appropriately. If the list's columns are too wide to -fit within the window, we use a horizontal scrollbar. Otherwise, we expand the -right-most column to take up the remaining free space in the list. This method is -called automatically when the ListCtrl is resized; you can also call it yourself -whenever you want the last column to be resized appropriately (eg, when adding, -removing or resizing columns). 'minWidth' is the preferred minimum width for +
Resize the last column appropriately. If the list's columns are too wide to +fit within the window, we use a horizontal scrollbar. Otherwise, we expand the +right-most column to take up the remaining free space in the list. This method is +called automatically when the ListCtrl is resized; you can also call it yourself +whenever you want the last column to be resized appropriately (eg, when adding, +removing or resizing columns). 'minWidth' is the preferred minimum width for the last column.
@@ -481,7 +475,7 @@ the last column.

Mixin that defines a platform independent selection policy -

As selection single and multi-select list return the item index or a +

As selection single and multi-select list return the item index or a list of item indexes respectively.

Methods
@@ -497,7 +491,7 @@ list of item indexes respectively.
Override to implement dynamic menus (destroy).
getSelection() -
Returns the current selection (or selections as a Python list if extended +
Returns the current selection (or selections as a Python list if extended selection is enabled) diff --git a/demo/ListCtrl_edit.py b/demo/ListCtrl_edit.py index f352931e..9ae7e044 100644 --- a/demo/ListCtrl_edit.py +++ b/demo/ListCtrl_edit.py @@ -49,9 +49,9 @@ class TestListCtrl(wx.ListCtrl, items = listctrldata.items() for key, data in items: - index = self.InsertStringItem(sys.maxint, data[0]) - self.SetStringItem(index, 1, data[1]) - self.SetStringItem(index, 2, data[2]) + index = self.InsertItem(sys.maxint, data[0]) + self.SetItem(index, 1, data[1]) + self.SetItem(index, 2, data[2]) self.SetItemData(index, key) self.SetColumnWidth(0, wx.LIST_AUTOSIZE) @@ -60,22 +60,20 @@ class TestListCtrl(wx.ListCtrl, self.currentItem = 0 - def SetStringItem(self, index, col, data): if col in range(3): - wx.ListCtrl.SetStringItem(self, index, col, data) - wx.ListCtrl.SetStringItem(self, index, 3+col, str(len(data))) + wx.ListCtrl.SetItem(self, index, col, data) + wx.ListCtrl.SetItem(self, index, 3+col, str(len(data))) else: try: datalen = int(data) except: return - wx.ListCtrl.SetStringItem(self, index, col, data) + wx.ListCtrl.SetItem(self, index, col, data) data = self.GetItem(index, col-3).GetText() - wx.ListCtrl.SetStringItem(self, index, col-3, data[0:datalen]) - + wx.ListCtrl.SetItem(self, index, col-3, data[0:datalen]) @@ -87,11 +85,11 @@ class TestListCtrlPanel(wx.Panel): tID = wx.NewId() sizer = wx.BoxSizer(wx.VERTICAL) - + if wx.Platform == "__WXMAC__" and \ hasattr(wx.GetApp().GetTopWindow(), "LoadDemo"): self.useNative = wx.CheckBox(self, -1, "Use native listctrl") - self.useNative.SetValue( + self.useNative.SetValue( not wx.SystemOptions.GetOptionInt("mac.listctrl.always_use_generic") ) self.Bind(wx.EVT_CHECKBOX, self.OnUseNative, self.useNative) sizer.Add(self.useNative, 0, wx.ALL | wx.ALIGN_RIGHT, 4) @@ -108,7 +106,7 @@ class TestListCtrlPanel(wx.Panel): def OnUseNative(self, event): - wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", not event.IsChecked()) + wx.SystemOptions.SetOption("mac.listctrl.always_use_generic", not event.IsChecked()) wx.GetApp().GetTopWindow().LoadDemo("ListCtrl_edit") diff --git a/demo/ListCtrl_virtual.py b/demo/ListCtrl_virtual.py index ff211aa2..594d2efb 100644 --- a/demo/ListCtrl_virtual.py +++ b/demo/ListCtrl_virtual.py @@ -7,7 +7,7 @@ import images class TestVirtualList(wx.ListCtrl): def __init__(self, parent, log): wx.ListCtrl.__init__( - self, parent, -1, + self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES ) @@ -41,17 +41,16 @@ class TestVirtualList(wx.ListCtrl): def makeBlank(self): - empty = wx.EmptyBitmap(16,16,32) + empty = wx.Bitmap(16,16,32) dc = wx.MemoryDC(empty) dc.SetBackground(wx.Brush((0,0,0,0))) dc.Clear() del dc empty.SetMaskColour((0,0,0)) return empty - def OnItemSelected(self, event): - self.currentItem = event.m_itemIndex + self.currentItem = event.Index self.log.WriteText('OnItemSelected: "%s", "%s", "%s", "%s"\n' % (self.currentItem, self.GetItemText(self.currentItem), @@ -59,7 +58,7 @@ class TestVirtualList(wx.ListCtrl): self.getColumnText(self.currentItem, 2))) def OnItemActivated(self, event): - self.currentItem = event.m_itemIndex + self.currentItem = event.Index self.log.WriteText("OnItemActivated: %s\nTopItem: %s\n" % (self.GetItemText(self.currentItem), self.GetTopItem())) @@ -68,7 +67,7 @@ class TestVirtualList(wx.ListCtrl): return item.GetText() def OnItemDeselected(self, evt): - self.log.WriteText("OnItemDeselected: %s" % evt.m_itemIndex) + self.log.WriteText("OnItemDeselected: %s" % evt.Index) #----------------------------------------------------------------- @@ -97,24 +96,24 @@ class TestVirtualList(wx.ListCtrl): class TestVirtualListPanel(wx.Panel): def __init__(self, parent, log): wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS) - + self.log = log sizer = wx.BoxSizer(wx.VERTICAL) - + if wx.Platform == "__WXMAC__" and \ hasattr(wx.GetApp().GetTopWindow(), "LoadDemo"): self.useNative = wx.CheckBox(self, -1, "Use native listctrl") - self.useNative.SetValue( + self.useNative.SetValue( not wx.SystemOptions.GetOptionInt("mac.listctrl.always_use_generic") ) self.Bind(wx.EVT_CHECKBOX, self.OnUseNative, self.useNative) sizer.Add(self.useNative, 0, wx.ALL | wx.ALIGN_RIGHT, 4) - + self.list = TestVirtualList(self, self.log) sizer.Add(self.list, 1, wx.EXPAND) - + self.SetSizer(sizer) self.SetAutoLayout(True) - + def OnUseNative(self, event): wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", not event.IsChecked()) wx.GetApp().GetTopWindow().LoadDemo("ListCtrl_virtual") diff --git a/demo/MDIDemo.py b/demo/MDIDemo.py index d884f114..b384fe3e 100644 --- a/demo/MDIDemo.py +++ b/demo/MDIDemo.py @@ -1,9 +1,9 @@ import wx -# Importing ScrolledWindow demo to make use of the MyCanvas +# Importing ScrolledWindow demo to make use of the MyCanvas # class defined within. -import ScrolledWindow +import ScrolledWindow import images SHOW_BACKGROUND = 1 @@ -42,23 +42,24 @@ class MyParentFrame(wx.MDIParentFrame): def OnExit(self, evt): self.Close(True) - def OnNewWindow(self, evt): self.winCount = self.winCount + 1 win = wx.MDIChildFrame(self, -1, "Child Window: %d" % self.winCount) canvas = ScrolledWindow.MyCanvas(win) win.Show(True) - def OnEraseBackground(self, evt): dc = evt.GetDC() # tile the background bitmap - sz = self.GetClientSize() + try: + sz = self.GetClientSize() + except RuntimeError:#closing demo + return w = self.bg_bmp.GetWidth() h = self.bg_bmp.GetHeight() x = 0 - + while x < sz.width: y = 0 @@ -74,14 +75,12 @@ class MyParentFrame(wx.MDIParentFrame): if __name__ == '__main__': class MyApp(wx.App): def OnInit(self): + wx.InitAllImageHandlers() frame = MyParentFrame() frame.Show(True) self.SetTopWindow(frame) return True - app = MyApp(False) app.MainLoop() - - diff --git a/demo/MDISashDemo.py b/demo/MDISashDemo.py index ad7b3261..b9a78e5b 100644 --- a/demo/MDISashDemo.py +++ b/demo/MDISashDemo.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import wx +import wx.adv import ScrolledWindow @@ -42,7 +43,7 @@ class MyParentFrame(wx.MDIParentFrame): self.Bind(wx.EVT_MENU, self.OnExit, id=ID_Menu_Exit) self.Bind( - wx.EVT_SASH_DRAGGED_RANGE, self.OnSashDrag, id=ID_WINDOW_TOP, + wx.adv.EVT_SASH_DRAGGED_RANGE, self.OnSashDrag, id=ID_WINDOW_TOP, id2=ID_WINDOW_BOTTOM ) @@ -51,34 +52,34 @@ class MyParentFrame(wx.MDIParentFrame): # Create some layout windows # A window like a toolbar - win = wx.SashLayoutWindow(self, ID_WINDOW_TOP, style=wx.NO_BORDER|wx.SW_3D) + win = wx.adv.SashLayoutWindow(self, ID_WINDOW_TOP, style=wx.NO_BORDER|wx.adv.SW_3D) win.SetDefaultSize((1000, 30)) - win.SetOrientation(wx.LAYOUT_HORIZONTAL) - win.SetAlignment(wx.LAYOUT_TOP) + win.SetOrientation(wx.adv.LAYOUT_HORIZONTAL) + win.SetAlignment(wx.adv.LAYOUT_TOP) win.SetBackgroundColour(wx.Colour(255, 0, 0)) - win.SetSashVisible(wx.SASH_BOTTOM, True) + win.SetSashVisible(wx.adv.SASH_BOTTOM, True) self.topWindow = win # A window like a statusbar - win = wx.SashLayoutWindow(self, ID_WINDOW_BOTTOM, style=wx.NO_BORDER|wx.SW_3D) + win = wx.adv.SashLayoutWindow(self, ID_WINDOW_BOTTOM, style=wx.NO_BORDER|wx.adv.SW_3D) win.SetDefaultSize((1000, 30)) - win.SetOrientation(wx.LAYOUT_HORIZONTAL) - win.SetAlignment(wx.LAYOUT_BOTTOM) + win.SetOrientation(wx.adv.LAYOUT_HORIZONTAL) + win.SetAlignment(wx.adv.LAYOUT_BOTTOM) win.SetBackgroundColour(wx.Colour(0, 0, 255)) - win.SetSashVisible(wx.SASH_TOP, True) + win.SetSashVisible(wx.adv.SASH_TOP, True) self.bottomWindow = win # A window to the left of the client window - win = wx.SashLayoutWindow(self, ID_WINDOW_LEFT1, style=wx.NO_BORDER|wx.SW_3D) + win = wx.adv.SashLayoutWindow(self, ID_WINDOW_LEFT1, style=wx.NO_BORDER|wx.adv.SW_3D) win.SetDefaultSize((120, 1000)) - win.SetOrientation(wx.LAYOUT_VERTICAL) - win.SetAlignment(wx.LAYOUT_LEFT) + win.SetOrientation(wx.adv.LAYOUT_VERTICAL) + win.SetAlignment(wx.adv.LAYOUT_LEFT) win.SetBackgroundColour(wx.Colour(0, 255, 0)) - win.SetSashVisible(wx.SASH_RIGHT, True) + win.SetSashVisible(wx.adv.SASH_RIGHT, True) win.SetExtraBorderSize(10) textWindow = wx.TextCtrl(win, -1, "", style=wx.TE_MULTILINE|wx.SUNKEN_BORDER) textWindow.SetValue("A sub window") @@ -87,22 +88,22 @@ class MyParentFrame(wx.MDIParentFrame): # Another window to the left of the client window - win = wx.SashLayoutWindow(self, ID_WINDOW_LEFT2, style=wx.NO_BORDER|wx.SW_3D) + win = wx.adv.SashLayoutWindow(self, ID_WINDOW_LEFT2, style=wx.NO_BORDER|wx.adv.SW_3D) win.SetDefaultSize((120, 1000)) - win.SetOrientation(wx.LAYOUT_VERTICAL) - win.SetAlignment(wx.LAYOUT_LEFT) + win.SetOrientation(wx.adv.LAYOUT_VERTICAL) + win.SetAlignment(wx.adv.LAYOUT_LEFT) win.SetBackgroundColour(wx.Colour(0, 255, 255)) - win.SetSashVisible(wx.SASH_RIGHT, True) + win.SetSashVisible(wx.adv.SASH_RIGHT, True) self.leftWindow2 = win def OnSashDrag(self, event): - if event.GetDragStatus() == wx.SASH_STATUS_OUT_OF_RANGE: + if event.GetDragStatus() == wx.adv.SASH_STATUS_OUT_OF_RANGE: return eID = event.GetId() - + if eID == ID_WINDOW_TOP: self.topWindow.SetDefaultSize((1000, event.GetDragRect().height)) @@ -115,12 +116,12 @@ class MyParentFrame(wx.MDIParentFrame): elif eID == ID_WINDOW_BOTTOM: self.bottomWindow.SetDefaultSize((1000, event.GetDragRect().height)) - wx.LayoutAlgorithm().LayoutMDIFrame(self) + wx.adv.LayoutAlgorithm().LayoutMDIFrame(self) self.GetClientWindow().Refresh() def OnSize(self, event): - wx.LayoutAlgorithm().LayoutMDIFrame(self) + wx.adv.LayoutAlgorithm().LayoutMDIFrame(self) def OnExit(self, evt): @@ -139,6 +140,7 @@ class MyParentFrame(wx.MDIParentFrame): if __name__ == '__main__': class MyApp(wx.App): def OnInit(self): + wx.InitAllImageHandlers() frame = MyParentFrame() frame.Show(True) self.SetTopWindow(frame) diff --git a/demo/MVCTree.py b/demo/MVCTree.py index 3f1f5256..ebe9ac16 100644 --- a/demo/MVCTree.py +++ b/demo/MVCTree.py @@ -37,13 +37,13 @@ def runTest(frame, nb, log): # p.AddEditor(FileEditor(p)) p.SetMultiSelect(True) - tree.EVT_MVCTREE_SEL_CHANGING(p, p.GetId(), selchanging) - tree.EVT_MVCTREE_SEL_CHANGED(p, p.GetId(), selchanged) - tree.EVT_MVCTREE_ITEM_EXPANDED(p, p.GetId(), expanded) - tree.EVT_MVCTREE_ITEM_COLLAPSED(p, p.GetId(), closed) - tree.EVT_MVCTREE_ADD_ITEM(p, p.GetId(), add) - tree.EVT_MVCTREE_DELETE_ITEM(p, p.GetId(), delitem) - tree.EVT_MVCTREE_KEY_DOWN(p, p.GetId(), key) + p.Bind(tree.EVT_MVCTREE_SEL_CHANGING, selchanging) + p.Bind(tree.EVT_MVCTREE_SEL_CHANGED, selchanged) + p.Bind(tree.EVT_MVCTREE_ITEM_EXPANDED, expanded) + p.Bind(tree.EVT_MVCTREE_ITEM_COLLAPSED, closed) + p.Bind(tree.EVT_MVCTREE_ADD_ITEM, add) + p.Bind(tree.EVT_MVCTREE_DELETE_ITEM, delitem) + p.Bind(tree.EVT_MVCTREE_KEY_DOWN, key) return p #frame.otherWin = f diff --git a/demo/Main.py b/demo/Main.py index f3ff53b6..a0ab7e9c 100644 --- a/demo/Main.py +++ b/demo/Main.py @@ -6,7 +6,7 @@ # Author: Robin Dunn # # Created: A long time ago, in a galaxy far, far away... -# RCS-ID: $Id$ +# RCS-ID: $Id: Main.py 71772 2012-06-14 22:37:10Z RD $ # Copyright: (c) 1999 by Total Control Software # Licence: wxWindows license #---------------------------------------------------------------------------- @@ -56,11 +56,13 @@ import cPickle, cStringIO, re, urllib2 import shutil from threading import Thread -import wx -import wx.aui +import wx +import wx.adv +import wx.lib.agw.aui as aui import wx.html from wx.lib.msgpanel import MessagePanel - +from wx.adv import TaskBarIcon as TaskBarIcon +from wx.adv import SplashScreen as SplashScreen import wx.lib.mixins.inspection import version @@ -71,8 +73,8 @@ images = None # For debugging ##wx.Trap(); -##print "wx.VERSION_STRING = %s (%s)" % (wx.VERSION_STRING, wx.USE_UNICODE and 'unicode' or 'ansi') -##print "pid:", os.getpid() +##print("wx.VERSION_STRING = %s (%s)" % (wx.VERSION_STRING, wx.USE_UNICODE and 'unicode' or 'ansi')) +##print("pid:", os.getpid()) ##raw_input("Press Enter...") #--------------------------------------------------------------------------- @@ -89,6 +91,7 @@ _demoPngs = ["overview", "recent", "frame", "dialog", "moredialog", "core", _treeList = [ # new stuff ('Recent Additions/Updates', [ + 'BannerWindow', 'PropertyGrid', 'SystemSettings', 'GridLabelRenderer', @@ -171,7 +174,7 @@ _treeList = [ 'RadioButton', 'SashWindow', 'ScrolledWindow', - 'SearchCtrl', + 'SearchCtrl', 'Slider', 'SpinButton', 'SpinCtrl', @@ -188,7 +191,7 @@ _treeList = [ 'TreeCtrl', 'Validator', ]), - + ('"Book" Controls', [ 'AUI_Notebook', 'Choicebook', @@ -233,13 +236,13 @@ _treeList = [ 'ExpandoTextCtrl', 'FancyText', 'FileBrowseButton', - 'FloatBar', + 'FloatBar', 'FloatCanvas', 'HtmlWindow', 'HTML2_WebView', 'InfoBar', 'IntCtrl', - 'MVCTree', + 'MVCTree', 'MaskedEditControls', 'MaskedNumCtrl', 'MediaCtrl', @@ -263,7 +266,7 @@ _treeList = [ 'TreeMixin', 'VListBox', ]), - + # How to lay out the controls in a frame/dialog ('Window Layout', [ 'GridBagSizer', @@ -331,7 +334,7 @@ _treeList = [ 'GraphicsContext', 'GraphicsGradient', 'GLCanvas', - 'I18N', + 'I18N', 'Joystick', 'MimeTypesManager', 'MouseGestures', @@ -349,7 +352,6 @@ _treeList = [ 'Unicode', ]), - ('Check out the samples dir too', [] ), ] @@ -367,7 +369,7 @@ _eventTable = '

Events

\n' \ _appearanceTable = '

Appearance

\n' \ '

Control appearance on various platform:\n' \ '

' - + _styleHeaders = ["Style Name", "Description"] _eventHeaders = ["Event Name", "Description"] _headerTable = '' @@ -387,7 +389,7 @@ _importList = ["wx.aui", "wx.calendar", "wx.html", "wx.media", "wx.wizard", "wx.combo", "wx.animate", "wx.gizmos", "wx.glcanvas", "wx.grid", "wx.richtext", "wx.stc"] -_dirWX = dir(wx) +_dirWX = dir(wx) for mod in _importList: try: module = __import__(mod) @@ -405,7 +407,7 @@ def ReplaceCapitals(string): * `string`: the string to be analyzed. """ - + newString = "" for char in string: if char.isupper(): @@ -415,7 +417,7 @@ def ReplaceCapitals(string): return newString - + def RemoveHTMLTags(data): """ Removes all the HTML tags from a string. @@ -440,7 +442,7 @@ def FormatDocs(keyword, values, num): text = "
" + table%(keyword.lower(), keyword.lower()) + "\n\n" else: text = "
" + table - + for indx in xrange(2): text += _headerTable%headers[indx] @@ -449,16 +451,16 @@ def FormatDocs(keyword, values, num): for name in names: text += "\n" - + description = values[name].strip() pythonValue = name.replace("wx", "wx.") if num == 3: - + colour = "#ff0000" value = "Unavailable" cutValue = pythonValue[3:] - + if cutValue in _dirWX: try: val = eval(pythonValue) @@ -475,19 +477,19 @@ def FormatDocs(keyword, values, num): pythonValue = "%s.%s"%(packages, cutValue) break - text += _styleTag%pythonValue + "\n" + text += _styleTag%pythonValue + "\n" else: text += _eventTag%pythonValue + "\n" - + text += _description%FormatDescription(description) + "\n" text += "\n" text += "\n
%s
\n\n

" return text - + def FormatDescription(description): """ Formats a wxWidgets C++ description in a more wxPython-based way. @@ -506,7 +508,7 @@ def FormatDescription(description): def FormatImages(appearance): - text = "


" + _appearanceTable + text = "


" + _appearanceTable for indx in xrange(2): text += "\n\n" @@ -523,7 +525,7 @@ def FormatImages(appearance): text += "\n\n\n

" return text - + def FindWindowStyles(text, originalText, widgetName): """ Finds the windows styles and events in the input text. @@ -538,12 +540,12 @@ def FindWindowStyles(text, originalText, widgetName): winStyles, winEvents, winExtra, winAppearance = {}, {}, {}, {} inStyle = inExtra = inEvent = False - + for line in text: if "following styles:" in line: inStyle = True continue - + elif "Event macros" in line: inEvent = True continue @@ -555,25 +557,25 @@ def FindWindowStyles(text, originalText, widgetName): if "Appearance:" in line: winAppearance = FindImages(originalText, widgetName) continue - + elif not line.strip(): inStyle = inEvent = inExtra = False continue if inStyle: start = line.index(':') - windowStyle = line[0:start] + windowStyle = line[0:start] styleDescription = line[start+1:] winStyles[windowStyle] = styleDescription elif inEvent: start = line.index(':') eventName = line[0:start] - eventDescription = line[start+1:] + eventDescription = line[start+1:] winEvents[eventName] = eventDescription elif inExtra: start = line.index(':') styleName = line[0:start] - styleDescription = line[start+1:] + styleDescription = line[start+1:] winExtra[styleName] = styleDescription return winStyles, winEvents, winExtra, winAppearance @@ -592,7 +594,7 @@ def FindImages(text, widgetName): winAppearance = {} start = text.find("class='appearance'") - + if start < 0: return winAppearance @@ -609,7 +611,7 @@ def FindImages(text, widgetName): possibleImage = possibleImage.replace("'", "") f = urllib2.urlopen(_trunkURL + possibleImage) stream = f.read() - + elif "alt=" in items: plat = items.replace("alt=", "").replace("'", "").strip() path = os.path.join(imagesDir, plat, widgetName + ".png") @@ -618,7 +620,7 @@ def FindImages(text, widgetName): image.SaveFile(path, wx.BITMAP_TYPE_PNG) winAppearance[plat] = path - + return winAppearance @@ -628,9 +630,9 @@ def FindImages(text, widgetName): class InternetThread(Thread): """ Worker thread class to attempt connection to the internet. """ - + def __init__(self, notifyWindow, selectedClass): - + Thread.__init__(self) self.notifyWindow = notifyWindow @@ -639,11 +641,11 @@ class InternetThread(Thread): self.setDaemon(True) self.start() - + def run(self): """ Run the worker thread. """ - + # This is the code executing in the new thread. Simulation of # a long process as a simple urllib2 call @@ -657,7 +659,7 @@ class InternetThread(Thread): if not self.keepRunning: return - + wx.CallAfter(self.notifyWindow.LoadDocumentation, data) except (IOError, urllib2.HTTPError): # Unable to get to the internet @@ -674,9 +676,9 @@ class InternetThread(Thread): #--------------------------------------------------------------------------- # Show how to derive a custom wxLog class -class MyLog(wx.PyLog): +class MyLog(wx.Log): def __init__(self, textCtrl, logTime=0): - wx.PyLog.__init__(self) + wx.Log.__init__(self) self.tc = textCtrl self.logTime = logTime @@ -704,8 +706,8 @@ try: # Some methods to make it compatible with how the wxTextCtrl is used def SetValue(self, value): - if wx.USE_UNICODE: - value = value.decode('iso8859_1') + # if wx.USE_UNICODE: + # value = value.decode('iso8859_1') val = self.GetReadOnly() self.SetReadOnly(False) self.SetText(value) @@ -751,31 +753,31 @@ try: start = self.PositionFromLine(line) end = self.GetLineEndPosition(line) self.SetSelection(start, end) - + def SetUpEditor(self): """ - This method carries out the work of setting up the demo editor. + This method carries out the work of setting up the demo editor. It's seperate so as not to clutter up the init code. """ import keyword - + self.SetLexer(stc.STC_LEX_PYTHON) self.SetKeyWords(0, " ".join(keyword.kwlist)) - + # Enable folding - self.SetProperty("fold", "1" ) + self.SetProperty("fold", "1" ) # Highlight tab/space mixing (shouldn't be any) self.SetProperty("tab.timmy.whinge.level", "1") # Set left and right margins self.SetMargins(2,2) - + # Set up the numbers in the margin for margin #1 self.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER) # Reasonable value for, say, 4-5 digits using a mono font (40 pix) self.SetMarginWidth(1, 40) - + # Indentation and tab stuff self.SetIndent(4) # Proscribed indent size for wx self.SetIndentationGuides(True) # Show indent guides @@ -783,25 +785,25 @@ try: self.SetTabIndents(True) # Tab key indents self.SetTabWidth(4) # Proscribed tab size for wx self.SetUseTabs(False) # Use spaces rather than tabs, or - # TabTimmy will complain! + # TabTimmy will complain! # White space self.SetViewWhiteSpace(False) # Don't view white space - + # EOL: Since we are loading/saving ourselves, and the # strings will always have \n's in them, set the STC to - # edit them that way. + # edit them that way. self.SetEOLMode(wx.stc.STC_EOL_LF) self.SetViewEOL(False) - + # No right-edge mode indicator self.SetEdgeMode(stc.STC_EDGE_NONE) - + # Setup a margin to hold fold markers self.SetMarginType(2, stc.STC_MARGIN_SYMBOL) self.SetMarginMask(2, stc.STC_MASK_FOLDERS) self.SetMarginSensitive(2, True) self.SetMarginWidth(2, 12) - + # and now set up the fold markers self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "black") self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "black") @@ -810,21 +812,21 @@ try: self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "black") self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "black") self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "black") - + # Global default style if wx.Platform == '__WXMSW__': - self.StyleSetSpec(stc.STC_STYLE_DEFAULT, + self.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier New') elif wx.Platform == '__WXMAC__': - # TODO: if this looks fine on Linux too, remove the Mac-specific case + # TODO: if this looks fine on Linux too, remove the Mac-specific case # and use this whenever OS != MSW. - self.StyleSetSpec(stc.STC_STYLE_DEFAULT, + self.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Monaco') else: defsize = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT).GetPointSize() - self.StyleSetSpec(stc.STC_STYLE_DEFAULT, + self.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier,size:%d'%defsize) - + # Clear styles and revert to default. self.StyleClearAll() @@ -832,14 +834,14 @@ try: # The rest remains unchanged. # Line numbers in margin - self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2') + self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2') # Highlighted brace self.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT,'fore:#00009D,back:#FFFF00') # Unmatched brace self.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD,'fore:#00009D,back:#FF0000') # Indentation guide self.StyleSetSpec(wx.stc.STC_STYLE_INDENTGUIDE, "fore:#CDCDCD") - + # Python styles self.StyleSetSpec(wx.stc.STC_P_DEFAULT, 'fore:#000000') # Comments @@ -870,8 +872,8 @@ try: # Selection background self.SetSelBackground(1, '#66CCFF') - self.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT)) - self.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)) + self.SetSelBackground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT)) + self.SetSelForeground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)) def RegisterModifiedEvent(self, eventHandler): self.Bind(wx.stc.EVT_STC_CHANGE, eventHandler) @@ -889,7 +891,7 @@ except ImportError: def SetReadOnly(self, flag): self.SetEditable(not flag) # NOTE: STC already has this method - + def GetText(self): return self.GetValue() @@ -942,7 +944,7 @@ class DemoCodePanel(wx.Panel): self.controlBox.Add(radioButton, 0, wx.EXPAND | wx.RIGHT, 5) radioButton.modID = modID # makes it easier for the event handler radioButton.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton) - + self.controlBox.Add(self.btnSave, 0, wx.RIGHT, 5) self.controlBox.Add(self.btnRestore, 0) @@ -950,7 +952,7 @@ class DemoCodePanel(wx.Panel): self.box.Add(self.controlBox, 0, wx.EXPAND) self.box.Add(wx.StaticLine(self), 0, wx.EXPAND) self.box.Add(self.editor, 1, wx.EXPAND) - + self.box.Fit(self) self.SetSizer(self.box) @@ -969,11 +971,11 @@ class DemoCodePanel(wx.Panel): def ActiveModuleChanged(self): self.LoadDemoSource(self.demoModules.GetSource()) self.UpdateControlState() - self.mainFrame.pnl.Freeze() + self.mainFrame.pnl.Freeze() self.ReloadDemo() self.mainFrame.pnl.Thaw() - + def LoadDemoSource(self, source): self.editor.Clear() self.editor.SetValue(source) @@ -986,8 +988,8 @@ class DemoCodePanel(wx.Panel): self.editor.SetFocus() if highlight: self.editor.SelectLine(line) - - + + def UpdateControlState(self): active = self.demoModules.GetActiveID() # Update the radio/restore buttons @@ -1007,7 +1009,7 @@ class DemoCodePanel(wx.Panel): if moduleID == modModified: self.btnRestore.Enable(False) - + def OnRadioButton(self, event): radioSelected = event.GetEventObject() modSelected = radioSelected.modID @@ -1021,11 +1023,11 @@ class DemoCodePanel(wx.Panel): if self.demoModules.name != __name__: self.mainFrame.RunModule() - + def OnCodeModified(self, event): self.btnSave.Enable(self.editor.IsModified()) - + def OnSave(self, event): if self.demoModules.Exists(modModified): if self.demoModules.GetActiveID() == modOriginal: @@ -1037,7 +1039,7 @@ class DemoCodePanel(wx.Panel): if result == wx.ID_NO: return dlg.Destroy() - + self.demoModules.SetActive(modModified) modifiedFilename = GetModifiedFilename(self.demoModules.name) @@ -1053,7 +1055,7 @@ class DemoCodePanel(wx.Panel): return else: wx.LogMessage("Created directory for modified demos: %s" % GetModifiedDirectory()) - + # Save f = open(modifiedFilename, "wt") source = self.editor.GetText() @@ -1061,7 +1063,7 @@ class DemoCodePanel(wx.Panel): f.write(source) finally: f.close() - + busy = wx.BusyInfo("Reloading demo module...") self.demoModules.LoadFromFile(modModified, modifiedFilename) self.ActiveModuleChanged() @@ -1074,7 +1076,7 @@ class DemoCodePanel(wx.Panel): self.demoModules.Delete(modModified) os.unlink(modifiedFilename) # Delete the modified copy busy = wx.BusyInfo("Reloading demo module...") - + self.ActiveModuleChanged() self.mainFrame.SetTreeModified(False) @@ -1125,7 +1127,7 @@ def GetOriginalFilename(name): if os.path.isfile(name): return name - + originalDir = os.getcwd() listDir = os.listdir(originalDir) # Loop over the content of the demo directory @@ -1135,7 +1137,7 @@ def GetOriginalFilename(name): continue dirFile = os.listdir(item) # See if a file called "name" is there - if name in dirFile: + if name in dirFile: return os.path.join(item, name) # We must return a string... @@ -1167,14 +1169,14 @@ def MakeDocDirs(): for plat in _platformNames: imageDir = os.path.join(docDir, "images", plat) - if not os.path.exists(imageDir): + if not os.path.exists(imageDir): os.makedirs(imageDir) - + def GetDocFile(): - + docFile = os.path.join(GetDataDir(), "docs", "TrunkDocs.pkl") - + return docFile @@ -1189,14 +1191,14 @@ def SearchDemo(name, keyword): fid = open(GetOriginalFilename(name), "rt") fullText = fid.read() fid.close() - + fullText = fullText.decode("iso-8859-1") if fullText.find(keyword) >= 0: return True - return False - + return False + def HuntExternalDemos(): """ @@ -1277,14 +1279,14 @@ def LookForExternals(externalDemos, demoName): # No match found, return None for both return pkg, overview - + #--------------------------------------------------------------------------- class ModuleDictWrapper(object): """Emulates a module with a dynamically compiled __dict__""" def __init__(self, dict): self.dict = dict - + def __getattr__(self, name): if name in self.dict: return self.dict[name] @@ -1299,16 +1301,16 @@ class DemoModules(object): def __init__(self, name): self.modActive = -1 self.name = name - - # (dict , source , filename , description , error information ) - # ( 0 , 1 , 2 , 3 , 4 ) + + # (dict , source , filename , description , error information ) + # ( 0 , 1 , 2 , 3 , 4 ) self.modules = [[dict(), "" , "" , "" , None], [dict(), "" , "" , "" , None]] - + for i in [modOriginal, modModified]: self.modules[i][0]['__file__'] = \ os.path.join(os.getcwdu(), GetOriginalFilename(name)) - + # load original module self.LoadFromFile(modOriginal, GetOriginalFilename(name)) self.SetActive(modOriginal) @@ -1335,9 +1337,9 @@ class DemoModules(object): source = self.modules[modID][1] description = self.modules[modID][2] description = description.encode(sys.getfilesystemencoding()) - + try: - code = compile(source, description, "exec") + code = compile(source, description, "exec") exec code in self.modules[modID][0] except: self.modules[modID][4] = DemoError(sys.exc_info()) @@ -1364,7 +1366,7 @@ class DemoModules(object): def GetActiveID(self): return self.modActive - + def GetSource(self, modID = None): if modID is None: modID = self.modActive @@ -1396,7 +1398,7 @@ class DemoModules(object): source = self.modules[modID][1] filename = self.modules[modID][2] - try: + try: file = open(filename, "wt") file.write(source) finally: @@ -1418,7 +1420,7 @@ class DemoError(object): """Wraps and stores information about the current exception""" def __init__(self, exc_info): import copy - + excType, excValue = exc_info[:2] # traceback list entries: (filename, line number, function name, text) self.traceback = traceback.extract_tb(exc_info[2]) @@ -1448,7 +1450,7 @@ class DemoError(object): self.exception_details = "" & type(excValue).__name__ del exc_info - + def __str__(self): ret = "Type %s \n \ Traceback: %s \n \ @@ -1483,7 +1485,7 @@ class DemoErrorPanel(wx.Panel): boxInfoGrid.Add(wx.StaticText(self, -1, demoError.exception_details) , 0, textFlags, 5 ) boxInfoSizer.Add(boxInfoGrid, 0, wx.ALIGN_CENTRE | wx.ALL, 5 ) self.box.Add(boxInfoSizer, 0, wx.ALIGN_CENTER | wx.ALL, 5) - + # Set up the traceback list # This one automatically resizes last column to take up remaining space from ListCtrl import TestListCtrl @@ -1512,11 +1514,11 @@ class DemoErrorPanel(wx.Panel): #Add the traceback data for x in range(len(traceback)): data = traceback[x] - list.InsertStringItem(x, os.path.basename(data[0])) # Filename - list.SetStringItem(x, 1, str(data[1])) # Line - list.SetStringItem(x, 2, str(data[2])) # Function - list.SetStringItem(x, 3, str(data[3])) # Code - + list.InsertItem(x, os.path.basename(data[0])) # Filename + list.SetItem(x, 1, str(data[1])) # Line + list.SetItem(x, 2, str(data[2])) # Function + list.SetItem(x, 3, str(data[3])) # Code + # Check whether this entry is from the demo module if data[0] == "" or data[0] == "": # FIXME: make more generalised self.list.SetItemData(x, int(data[1])) # Store line number for easy access @@ -1526,15 +1528,15 @@ class DemoErrorPanel(wx.Panel): self.list.SetItem(item) else: self.list.SetItemData(x, -1) # Editor can't jump into this one's code - + def OnItemSelected(self, event): # This occurs before OnDoubleClick and can be used to set the # currentItem. OnDoubleClick doesn't get a wxListEvent.... - self.currentItem = event.m_itemIndex + self.currentItem = event.Index event.Skip() - + def OnDoubleClick(self, event): # If double-clicking on a demo's entry, jump to the line number line = self.list.GetItemData(self.currentItem) @@ -1542,42 +1544,42 @@ class DemoErrorPanel(wx.Panel): self.nb.SetSelection(1) # Switch to the code viewer tab wx.CallAfter(self.codePanel.JumpToLine, line-1, True) event.Skip() - + #--------------------------------------------------------------------------- class MainPanel(wx.Panel): """ - Just a simple derived panel where we override Freeze and Thaw so they are - only used on wxMSW. + Just a simple derived panel where we override Freeze and Thaw to work + around an issue on wxGTK. """ def Freeze(self): - if 'wxMSW' in wx.PlatformInfo: + if not 'wxGTK' in wx.PlatformInfo: return super(MainPanel, self).Freeze() - + def Thaw(self): - if 'wxMSW' in wx.PlatformInfo: + if not 'wxGTK' in wx.PlatformInfo: return super(MainPanel, self).Thaw() - + #--------------------------------------------------------------------------- -class DemoTaskBarIcon(wx.TaskBarIcon): +class DemoTaskBarIcon(TaskBarIcon): TBMENU_RESTORE = wx.NewId() TBMENU_CLOSE = wx.NewId() TBMENU_CHANGE = wx.NewId() TBMENU_REMOVE = wx.NewId() - + def __init__(self, frame): - wx.TaskBarIcon.__init__(self, wx.TBI_DOCK) # wx.TBI_CUSTOM_STATUSITEM + TaskBarIcon.__init__(self, wx.adv.TBI_DOCK) # wx.adv.TBI_CUSTOM_STATUSITEM self.frame = frame # Set the image icon = self.MakeIcon(images.WXPdemo.GetImage()) self.SetIcon(icon, "wxPython Demo") self.imgidx = 1 - + # bind some events - self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate) + self.Bind(wx.adv.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate) self.Bind(wx.EVT_MENU, self.OnTaskBarActivate, id=self.TBMENU_RESTORE) self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE) self.Bind(wx.EVT_MENU, self.OnTaskBarChange, id=self.TBMENU_CHANGE) @@ -1610,9 +1612,9 @@ class DemoTaskBarIcon(wx.TaskBarIcon): elif "wxGTK" in wx.PlatformInfo: img = img.Scale(22, 22) # wxMac can be any size upto 128x128, so leave the source img alone.... - icon = wx.IconFromBitmap(img.ConvertToBitmap() ) + icon = wx.IconFromBitmap(img.ConvertToBitmap()) return icon - + def OnTaskBarActivate(self, evt): if self.frame.IsIconized(): @@ -1627,14 +1629,14 @@ class DemoTaskBarIcon(wx.TaskBarIcon): def OnTaskBarChange(self, evt): - names = [ "WXPdemo", "Mondrian", "Pencil", "Carrot" ] + names = [ "WXPdemo", "Mondrian", "Pencil", "Carrot" ] name = names[self.imgidx] - + eImg = getattr(images, name) self.imgidx += 1 if self.imgidx >= len(names): self.imgidx = 0 - + icon = self.MakeIcon(eImg.Image) self.SetIcon(icon, "This is a new icon: " + name) @@ -1646,7 +1648,7 @@ class DemoTaskBarIcon(wx.TaskBarIcon): #--------------------------------------------------------------------------- class wxPythonDemo(wx.Frame): - overviewText = "wxPython Demo" + overviewText = "wxPython Overview" def __init__(self, parent, title): wx.Frame.__init__(self, parent, -1, title, size = (970, 720), @@ -1655,8 +1657,8 @@ class wxPythonDemo(wx.Frame): self.SetMinSize((640,480)) self.pnl = pnl = MainPanel(self) - - self.mgr = wx.aui.AuiManager() + + self.mgr = aui.AuiManager() self.mgr.SetManagedWindow(pnl) self.loaded = False @@ -1675,9 +1677,9 @@ class wxPythonDemo(wx.Frame): self.tbicon = DemoTaskBarIcon(self) except: self.tbicon = None - + self.otherWin = None - + self.allowDocs = False self.downloading = False self.internetThread = None @@ -1693,31 +1695,31 @@ class wxPythonDemo(wx.Frame): self.Centre(wx.BOTH) - self.statusBar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusBar = self.CreateStatusBar(2)#, wx.ST_SIZEGRIP self.statusBar.SetStatusWidths([-2, -1]) statusText = "Welcome to wxPython %s"%version.VERSION_STRING self.statusBar.SetStatusText(statusText, 0) - - self.downloadGauge = wx.Gauge(self.statusBar, -1, 50) - self.downloadGauge.SetToolTipString("Downloading Docs...") + + self.downloadGauge = wx.Gauge(self.statusBar, wx.ID_ANY, 50) + self.downloadGauge.SetToolTip("Downloading Docs...") self.downloadGauge.Hide() self.sizeChanged = False self.Reposition() - + self.statusBar.Bind(wx.EVT_SIZE, self.OnStatusBarSize) self.statusBar.Bind(wx.EVT_IDLE, self.OnStatusBarIdle) self.dying = False self.skipLoad = False self.allowAuiFloating = False - + def EmptyHandler(evt): pass self.ReadConfigurationFile() - self.externalDemos = HuntExternalDemos() - + self.externalDemos = HuntExternalDemos() + # Create a Notebook self.nb = wx.Notebook(pnl, -1, style=wx.CLIP_CHILDREN) imgList = wx.ImageList(16, 16) @@ -1727,11 +1729,11 @@ class wxPythonDemo(wx.Frame): for indx in xrange(9): bmp = images.catalog["spinning_nb%d"%indx].GetBitmap() imgList.Add(bmp) - + self.nb.AssignImageList(imgList) self.BuildMenuBar() - + self.finddata = wx.FindReplaceData() self.finddata.SetFlags(wx.FR_DOWN) @@ -1739,9 +1741,9 @@ class wxPythonDemo(wx.Frame): leftPanel = wx.Panel(pnl, style=wx.TAB_TRAVERSAL|wx.CLIP_CHILDREN) self.treeMap = {} self.searchItems = {} - + self.tree = wxPythonDemoTree(leftPanel) - + self.filter = wx.SearchCtrl(leftPanel, style=wx.TE_PROCESS_ENTER) self.filter.ShowCancelButton(True) self.filter.Bind(wx.EVT_TEXT, self.RecreateTree) @@ -1762,12 +1764,12 @@ class wxPythonDemo(wx.Frame): self.tree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed) self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged) self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnTreeLeftDown) - + # Set up a wx.html.HtmlWindow on the Overview Notebook page # we put it in a panel first because there seems to be a # refresh bug of some sort (wxGTK) when it is directly in # the notebook... - + if 0: # the old way self.ovr = wx.html.HtmlWindow(self.nb, -1, size=(400, 400)) self.nb.AddPage(self.ovr, self.overviewText, imageId=0) @@ -1797,8 +1799,8 @@ class wxPythonDemo(wx.Frame): #wx.Log_SetActiveTarget(wx.LogTextCtrl(self.log)) # But instead of the above we want to show how to use our own wx.Log class - wx.Log_SetActiveTarget(MyLog(self.log)) - + wx.Log.SetActiveTarget(MyLog(self.log)) + # for serious debugging #wx.Log_SetActiveTarget(wx.LogStderr()) #wx.Log_SetTraceMask(wx.TraceMessages) @@ -1834,9 +1836,9 @@ class wxPythonDemo(wx.Frame): self.tree.EnsureVisible(selectedDemo) # Use the aui manager to set up everything - self.mgr.AddPane(self.nb, wx.aui.AuiPaneInfo().CenterPane().Name("Notebook")) + self.mgr.AddPane(self.nb, aui.AuiPaneInfo().CenterPane().Name("Notebook")) self.mgr.AddPane(leftPanel, - wx.aui.AuiPaneInfo(). + aui.AuiPaneInfo(). Left().Layer(2).BestSize((240, -1)). MinSize((240, -1)). Floatable(self.allowAuiFloating).FloatingSize((240, 700)). @@ -1844,7 +1846,7 @@ class wxPythonDemo(wx.Frame): CloseButton(False). Name("DemoTree")) self.mgr.AddPane(self.log, - wx.aui.AuiPaneInfo(). + aui.AuiPaneInfo(). Bottom().BestSize((-1, 150)). MinSize((-1, 140)). Floatable(self.allowAuiFloating).FloatingSize((500, 160)). @@ -1855,8 +1857,8 @@ class wxPythonDemo(wx.Frame): self.auiConfigurations[DEFAULT_PERSPECTIVE] = self.mgr.SavePerspective() self.mgr.Update() - self.mgr.SetFlags(self.mgr.GetFlags() ^ wx.aui.AUI_MGR_TRANSPARENT_DRAG) - + self.mgr.SetAGWFlags(self.mgr.GetAGWFlags() ^ aui.AUI_MGR_TRANSPARENT_DRAG) + def ReadConfigurationFile(self): @@ -1892,9 +1894,9 @@ class wxPythonDemo(wx.Frame): self.pickledData = cPickle.load(fid) except: self.pickledData = {} - + fid.close() - + def BuildMenuBar(self): @@ -1905,11 +1907,11 @@ class wxPythonDemo(wx.Frame): 'Redirect print statements to a window', wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnToggleRedirect, item) - + wx.App.SetMacExitMenuItemId(9123) exitItem = wx.MenuItem(menu, 9123, 'E&xit\tCtrl-Q', 'Get the heck outta here!') exitItem.SetBitmap(images.catalog['exit'].GetBitmap()) - menu.AppendItem(exitItem) + menu.Append(exitItem) self.Bind(wx.EVT_MENU, self.OnFileExit, exitItem) self.mainmenu.Append(menu, '&File') @@ -1923,64 +1925,64 @@ class wxPythonDemo(wx.Frame): self.Bind(wx.EVT_MENU, self.OnDemoMenu, mi) menuItem.SetBitmap(images.catalog[_demoPngs[indx+1]].GetBitmap()) menuItem.SetSubMenu(submenu) - menu.AppendItem(menuItem) + menu.Append(menuItem) self.mainmenu.Append(menu, '&Demo') # Make an Option menu menu = wx.Menu() item = wx.MenuItem(menu, -1, 'Allow download of docs', 'Docs for window styles and events from the web', wx.ITEM_CHECK) - menu.AppendItem(item) + menu.Append(item) item.Check(self.allowDocs) self.Bind(wx.EVT_MENU, self.OnAllowDownload, item) item = wx.MenuItem(menu, -1, 'Delete saved docs', 'Deletes the cPickle file where docs are stored') item.SetBitmap(images.catalog['deletedocs'].GetBitmap()) - menu.AppendItem(item) + menu.Append(item) self.Bind(wx.EVT_MENU, self.OnDeleteDocs, item) - + menu.AppendSeparator() item = wx.MenuItem(menu, -1, 'Allow floating panes', 'Allows the demo panes to be floated using wxAUI', wx.ITEM_CHECK) - menu.AppendItem(item) + menu.Append(item) item.Check(self.allowAuiFloating) self.Bind(wx.EVT_MENU, self.OnAllowAuiFloating, item) - + auiPerspectives = self.auiConfigurations.keys() auiPerspectives.sort() perspectivesMenu = wx.Menu() item = wx.MenuItem(perspectivesMenu, -1, DEFAULT_PERSPECTIVE, "Load startup default perspective", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item) - perspectivesMenu.AppendItem(item) + perspectivesMenu.Append(item) for indx, key in enumerate(auiPerspectives): if key == DEFAULT_PERSPECTIVE: continue item = wx.MenuItem(perspectivesMenu, -1, key, "Load user perspective %d"%indx, wx.ITEM_RADIO) - perspectivesMenu.AppendItem(item) + perspectivesMenu.Append(item) self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item) - menu.AppendMenu(wx.ID_ANY, "&AUI Perspectives", perspectivesMenu) + menu.Append(wx.ID_ANY, "&AUI Perspectives", perspectivesMenu) self.perspectives_menu = perspectivesMenu item = wx.MenuItem(menu, -1, 'Save Perspective', 'Save AUI perspective') item.SetBitmap(images.catalog['saveperspective'].GetBitmap()) - menu.AppendItem(item) + menu.Append(item) self.Bind(wx.EVT_MENU, self.OnSavePerspective, item) item = wx.MenuItem(menu, -1, 'Delete Perspective', 'Delete AUI perspective') item.SetBitmap(images.catalog['deleteperspective'].GetBitmap()) - menu.AppendItem(item) + menu.Append(item) self.Bind(wx.EVT_MENU, self.OnDeletePerspective, item) menu.AppendSeparator() item = wx.MenuItem(menu, -1, 'Restore Tree Expansion', 'Restore the initial tree expansion state') item.SetBitmap(images.catalog['expansion'].GetBitmap()) - menu.AppendItem(item) + menu.Append(item) self.Bind(wx.EVT_MENU, self.OnTreeExpansion, item) self.mainmenu.Append(menu, '&Options') self.options_menu = menu - + # Make a Help menu menu = wx.Menu() findItem = wx.MenuItem(menu, -1, '&Find\tCtrl-F', 'Find in the Demo Code') @@ -1990,18 +1992,18 @@ class wxPythonDemo(wx.Frame): else: findNextItem = wx.MenuItem(menu, -1, 'Find &Next\tCtrl-G', 'Find Next') findNextItem.SetBitmap(images.catalog['findnext'].GetBitmap()) - menu.AppendItem(findItem) - menu.AppendItem(findNextItem) + menu.Append(findItem) + menu.Append(findNextItem) menu.AppendSeparator() shellItem = wx.MenuItem(menu, -1, 'Open Py&Shell Window\tF5', 'An interactive interpreter window with the demo app and frame objects in the namesapce') shellItem.SetBitmap(images.catalog['pyshell'].GetBitmap()) - menu.AppendItem(shellItem) + menu.Append(shellItem) inspToolItem = wx.MenuItem(menu, -1, 'Open &Widget Inspector\tF6', 'A tool that lets you browse the live widgets and sizers in an application') inspToolItem.SetBitmap(images.catalog['inspect'].GetBitmap()) - menu.AppendItem(inspToolItem) + menu.Append(inspToolItem) if 'wxMac' not in wx.PlatformInfo: menu.AppendSeparator() helpItem = menu.Append(wx.ID_ABOUT, '&About wxPython Demo', 'wxPython RULES!!!') @@ -2019,7 +2021,7 @@ class wxPythonDemo(wx.Frame): self.mainmenu.Append(menu, '&Help') self.SetMenuBar(self.mainmenu) - self.EnableAUIMenu() + self.EnableAUIMenu() if False: # This is another way to set Accelerators, in addition to @@ -2031,14 +2033,14 @@ class wxPythonDemo(wx.Frame): (wx.ACCEL_NORMAL, wx.WXK_F9, shellItem.GetId()), ]) self.SetAcceleratorTable(aTable) - - #--------------------------------------------- + + #--------------------------------------------- def RecreateTree(self, evt=None): # Catch the search type (name or content) searchMenu = self.filter.GetMenu().GetMenuItems() fullSearch = searchMenu[1].IsChecked() - + if evt: if fullSearch: # Do not`scan all the demo files for every char @@ -2054,12 +2056,12 @@ class wxPythonDemo(wx.Frame): if prnt: current = (self.tree.GetItemText(item), self.tree.GetItemText(prnt)) - + self.tree.Freeze() self.tree.DeleteAllItems() self.root = self.tree.AddRoot("wxPython Overview") self.tree.SetItemImage(self.root, 0) - self.tree.SetItemPyData(self.root, 0) + self.tree.SetItemData(self.root, 0) treeFont = self.tree.GetFont() catFont = self.tree.GetFont() @@ -2070,16 +2072,16 @@ class wxPythonDemo(wx.Frame): # was the size of the same label in the default font. if USE_CUSTOMTREECTRL or 'wxMSW' not in wx.PlatformInfo: treeFont.SetPointSize(treeFont.GetPointSize()+2) - + treeFont.SetWeight(wx.BOLD) catFont.SetWeight(wx.BOLD) self.tree.SetItemFont(self.root, treeFont) - + firstChild = None selectItem = None filter = self.filter.GetValue() count = 0 - + for category, items in _treeList: count += 1 if filter: @@ -2090,19 +2092,19 @@ class wxPythonDemo(wx.Frame): if items: child = self.tree.AppendItem(self.root, category, image=count) self.tree.SetItemFont(child, catFont) - self.tree.SetItemPyData(child, count) + self.tree.SetItemData(child, count) if not firstChild: firstChild = child for childItem in items: image = count if DoesModifiedExist(childItem): image = len(_demoPngs) theDemo = self.tree.AppendItem(child, childItem, image=image) - self.tree.SetItemPyData(theDemo, count) + self.tree.SetItemData(theDemo, count) self.treeMap[childItem] = theDemo if current and (childItem, category) == current: selectItem = theDemo - - + + self.tree.Expand(self.root) if firstChild: self.tree.Expand(firstChild) @@ -2114,7 +2116,7 @@ class wxPythonDemo(wx.Frame): self.skipLoad = True self.tree.SelectItem(selectItem) self.skipLoad = False - + self.tree.Thaw() self.searchItems = {} @@ -2135,9 +2137,9 @@ class wxPythonDemo(wx.Frame): # reposition the download gauge def Reposition(self): - rect = self.statusBar.GetFieldRect(1) - self.downloadGauge.SetPosition((rect.x+2, rect.y+2)) - self.downloadGauge.SetSize((rect.width-4, rect.height-4)) + # rect = self.statusBar.GetFieldRect(1) + # self.downloadGauge.SetPosition((rect.x+2, rect.y+2)) + # self.downloadGauge.SetSize((rect.width-4, rect.height-4)) self.sizeChanged = False @@ -2146,12 +2148,12 @@ class wxPythonDemo(wx.Frame): # Catch the search type (name or content) searchMenu = self.filter.GetMenu().GetMenuItems() fullSearch = searchMenu[1].IsChecked() - + if fullSearch: self.OnSearch() else: self.RecreateTree() - + def OnSearch(self, event=None): @@ -2161,7 +2163,7 @@ class wxPythonDemo(wx.Frame): return wx.BeginBusyCursor() - + for category, items in _treeList: self.searchItems[category] = [] for childItem in items: @@ -2169,7 +2171,7 @@ class wxPythonDemo(wx.Frame): self.searchItems[category].append(childItem) wx.EndBusyCursor() - self.RecreateTree() + self.RecreateTree() def SetTreeModified(self, modified): @@ -2179,8 +2181,8 @@ class wxPythonDemo(wx.Frame): else: image = self.tree.GetItemPyData(item) self.tree.SetItemImage(item, image) - - + + def WriteText(self, text): if text[-1:] == '\n': text = text[:-1] @@ -2220,7 +2222,7 @@ class wxPythonDemo(wx.Frame): item = event.GetItem() itemText = self.tree.GetItemText(item) self.LoadDemo(itemText) - + self.StartDownload() #--------------------------------------------- @@ -2228,7 +2230,7 @@ class wxPythonDemo(wx.Frame): try: wx.BeginBusyCursor() self.pnl.Freeze() - + os.chdir(self.cwd) self.ShutdownDemoModule() @@ -2272,7 +2274,7 @@ class wxPythonDemo(wx.Frame): self.codePage = None self.codePage = DemoCodePanel(self.nb, self) self.codePage.LoadDemo(self.demoModules) - + #--------------------------------------------- def RunModule(self): """Runs the active module""" @@ -2280,11 +2282,11 @@ class wxPythonDemo(wx.Frame): module = self.demoModules.GetActive() self.ShutdownDemoModule() overviewText = "" - + # o The RunTest() for all samples must now return a window that can # be palced in a tab in the main notebook. # o If an error occurs (or has occurred before) an error tab is created. - + if module is not None: wx.LogMessage("Running demo module...") if hasattr(module, "overview"): @@ -2301,12 +2303,12 @@ class wxPythonDemo(wx.Frame): self.demoPage.SetBackgroundColour(bg) assert self.demoPage is not None, "runTest must return a window!" - + else: # There was a previous error in compiling or exec-ing self.demoPage = DemoErrorPanel(self.nb, self.codePage, self.demoModules.GetErrorInfo(), self) - + self.SetOverview(self.demoModules.name + " Overview", overviewText) if self.firstTime: @@ -2325,13 +2327,13 @@ class wxPythonDemo(wx.Frame): self.demoPage.ShutdownDemo() ## wx.YieldIfNeeded() # in case the page has pending events self.demoPage = None - + #--------------------------------------------- def UpdateNotebook(self, select = -1): nb = self.nb debug = False self.pnl.Freeze() - + def UpdatePage(page, pageText): pageExists = False pagePos = -1 @@ -2340,7 +2342,7 @@ class wxPythonDemo(wx.Frame): pageExists = True pagePos = i break - + if page: if not pageExists: # Add a new page @@ -2361,7 +2363,7 @@ class wxPythonDemo(wx.Frame): if debug: wx.LogMessage("DBG: DELETED %s" % pageText) else: if debug: wx.LogMessage("DBG: STILL GONE - %s" % pageText) - + if select == -1: select = nb.GetSelection() @@ -2372,15 +2374,15 @@ class wxPythonDemo(wx.Frame): nb.SetSelection(select) self.pnl.Thaw() - + #--------------------------------------------- def SetOverview(self, name, text): self.curOverview = text lead = text[:6] if lead != '' and lead != '': text = '
'.join(text.split('\n')) - if wx.USE_UNICODE: - text = text.decode('iso8859_1') + # if wx.USE_UNICODE: + # text = text.decode('iso8859_1') self.ovr.SetPage(text) self.nb.SetPageText(0, os.path.split(name)[1]) @@ -2394,7 +2396,7 @@ class wxPythonDemo(wx.Frame): item = self.tree.GetSelection() if self.tree.ItemHasChildren(item): return - + itemText = self.tree.GetItemText(item) if itemText in self.pickledData: @@ -2421,7 +2423,7 @@ class wxPythonDemo(wx.Frame): def StopDownload(self, error=None): self.downloadTimer.Stop() - + if not self.downloading: return @@ -2436,7 +2438,7 @@ class wxPythonDemo(wx.Frame): self.internetThread.keepRunning = False self.internetThread = None - + self.downloading = False self.downloadGauge.Hide() self.Reposition() @@ -2446,16 +2448,16 @@ class wxPythonDemo(wx.Frame): lead = text[:6] if lead != '' and lead != '': text = '
'.join(text.split('\n')) - + self.ovr.SetPage(text) #--------------------------------------------- def LoadDocumentation(self, data): - + text = self.curOverview addHtml = False - + if '' not in text and '' not in text: text = '
'.join(text.split('\n')) @@ -2463,7 +2465,7 @@ class wxPythonDemo(wx.Frame): if appearance: text += FormatImages(appearance) - + for names, values in zip(["Styles", "Extra Styles", "Events"], [styles, extra, events]): if not values: continue @@ -2477,12 +2479,12 @@ class wxPythonDemo(wx.Frame): self.pickledData[itemText] = data if wx.USE_UNICODE: - text = text.decode('iso8859_1') + text = text.decode('iso8859_1') self.StopDownload() self.ovr.SetPage(text) - #print "load time: ", time.time() - start - + #print("load time: ", time.time() - start) + # Menu methods def OnFileExit(self, *event): self.Close() @@ -2491,10 +2493,10 @@ class wxPythonDemo(wx.Frame): app = wx.GetApp() if event.Checked(): app.RedirectStdio() - print "Print statements and other standard output will now be directed to this window." + print("Print statements and other standard output will now be directed to this window.") else: app.RestoreStdio() - print "Print statements and other standard output will now be sent to the usual location." + print("Print statements and other standard output will now be sent to the usual location.") def OnAllowDownload(self, event): @@ -2516,22 +2518,22 @@ class wxPythonDemo(wx.Frame): if result == wx.ID_NO: dlg.Destroy() return - + dlg.Destroy() busy = wx.BusyInfo("Deleting downloaded data...") wx.SafeYield() - + pickledFile = GetDocFile() docDir = os.path.split(pickledFile)[0] - + if os.path.exists(docDir): shutil.rmtree(docDir, ignore_errors=True) self.pickledData = {} del busy self.sendDownloadError = True - + def OnAllowAuiFloating(self, event): @@ -2550,8 +2552,8 @@ class wxPythonDemo(wx.Frame): for indx in xrange(4, len(menuItems)-1): item = menuItems[indx] item.Enable(self.allowAuiFloating) - - + + def OnAUIPerspectives(self, event): perspective = self.perspectives_menu.GetLabel(event.GetId()) self.mgr.LoadPerspective(self.auiConfigurations[perspective]) @@ -2560,7 +2562,7 @@ class wxPythonDemo(wx.Frame): def OnSavePerspective(self, event): dlg = wx.TextEntryDialog(self, "Enter a name for the new perspective:", "AUI Configuration") - + dlg.SetValue(("Perspective %d")%(len(self.auiConfigurations)+1)) if dlg.ShowModal() != wx.ID_OK: return @@ -2572,11 +2574,11 @@ class wxPythonDemo(wx.Frame): wx.MessageBox("The selected perspective name:\n\n%s\n\nAlready exists."%perspectiveName, "Error", style=wx.ICON_ERROR) return - + item = wx.MenuItem(self.perspectives_menu, -1, dlg.GetValue(), "Load user perspective %d"%(len(self.auiConfigurations)+1), wx.ITEM_RADIO) - self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item) + self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item) self.perspectives_menu.AppendItem(item) item.Check(True) self.auiConfigurations.update({dlg.GetValue(): self.mgr.SavePerspective()}) @@ -2586,12 +2588,12 @@ class wxPythonDemo(wx.Frame): menuItems = self.perspectives_menu.GetMenuItems() lst = [] loadDefault = False - + for indx, item in enumerate(menuItems): if indx > 0: lst.append(item.GetLabel()) - - dlg = wx.MultiChoiceDialog(self, + + dlg = wx.MultiChoiceDialog(self, "Please select the perspectives\nyou would like to delete:", "Delete AUI Perspectives", lst) @@ -2614,8 +2616,8 @@ class wxPythonDemo(wx.Frame): def OnTreeExpansion(self, event): self.tree.SetExpansionState(self.expansionState) - - + + def OnHelpAbout(self, event): from About import MyAboutBox about = MyAboutBox(self) @@ -2625,7 +2627,7 @@ class wxPythonDemo(wx.Frame): def OnHelpFind(self, event): if self.finddlg != None: return - + self.nb.SetSelection(1) self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find", wx.FR_NOMATCHCASE | wx.FR_NOWHOLEWORD) @@ -2705,7 +2707,7 @@ class wxPythonDemo(wx.Frame): self.shell.Show() # Hook the close event of the main frame window so that we - # close the shell at the same time if it still exists + # close the shell at the same time if it still exists def CloseShell(evt): if self.shell: self.shell.Close() @@ -2726,7 +2728,7 @@ class wxPythonDemo(wx.Frame): wnd = self InspectionTool().Show(wnd, True) - + #--------------------------------------------- def OnCloseWindow(self, event): self.mgr.UnInit() @@ -2735,16 +2737,16 @@ class wxPythonDemo(wx.Frame): self.codePage = None self.mainmenu = None self.StopDownload() - - if self.tbicon is not None: - self.tbicon.Destroy() + + # if self.tbicon is not None: + # self.tbicon.Destroy() config = GetConfig() config.Write('ExpansionState', str(self.tree.GetExpansionState())) config.Write('AUIPerspectives', str(self.auiConfigurations)) config.Write('AllowDownloads', str(self.allowDocs)) config.Write('AllowAUIFloating', str(self.allowAuiFloating)) - + config.Flush() MakeDocDirs() @@ -2769,16 +2771,16 @@ class wxPythonDemo(wx.Frame): def OnDownloadTimer(self, event): self.downloadGauge.Pulse() - + self.downloadImage += 1 if self.downloadImage > 9: self.downloadImage = 3 - + self.nb.SetPageImage(0, self.downloadImage) ## wx.SafeYield() - + #--------------------------------------------- - + def ShowTip(self): config = GetConfig() showTipText = config.Read("tips") @@ -2786,13 +2788,13 @@ class wxPythonDemo(wx.Frame): showTip, index = eval(showTipText) else: showTip, index = (1, 0) - - if showTip: - tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index) - showTip = wx.ShowTip(self, tp) - index = tp.GetCurrentTip() - config.Write("tips", str( (showTip, index) )) - config.Flush() + + # if showTip: + # tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index) + # showTip = wx.ShowTip(self, tp) + # index = tp.GetCurrentTip() + # config.Write("tips", str( (showTip, index) )) + # config.Flush() #--------------------------------------------- def OnDemoMenu(self, event): @@ -2828,14 +2830,14 @@ class wxPythonDemo(wx.Frame): #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- -class MySplashScreen(wx.SplashScreen): +class MySplashScreen(SplashScreen): def __init__(self): bmp = wx.Image(opj("bitmaps/splash.png")).ConvertToBitmap() - wx.SplashScreen.__init__(self, bmp, - wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT, + SplashScreen.__init__(self, bmp, + wx.adv.SPLASH_CENTRE_ON_SCREEN | wx.adv.SPLASH_TIMEOUT, 5000, None, -1) self.Bind(wx.EVT_CLOSE, self.OnClose) - self.fc = wx.FutureCall(2000, self.ShowMain) + self.fc = wx.CallLater(2000, self.ShowMain) def OnClose(self, evt): @@ -2843,7 +2845,7 @@ class MySplashScreen(wx.SplashScreen): # destroyed evt.Skip() self.Hide() - + # if the timer is still running then go ahead and show the # main frame now if self.fc.IsRunning(): @@ -2869,7 +2871,7 @@ if USE_CUSTOMTREECTRL: TreeBaseClass = CT.CustomTreeCtrl else: TreeBaseClass = wx.TreeCtrl - + class wxPythonDemoTree(ExpansionState, TreeBaseClass): def __init__(self, parent): @@ -2881,35 +2883,29 @@ class wxPythonDemoTree(ExpansionState, TreeBaseClass): self.SetWindowStyle(self.GetWindowStyle() & ~wx.TR_LINES_AT_ROOT) self.SetInitialSize((100,80)) - - + + def AppendItem(self, parent, text, image=-1, wnd=None): if USE_CUSTOMTREECTRL: item = TreeBaseClass.AppendItem(self, parent, text, image=image, wnd=wnd) else: item = TreeBaseClass.AppendItem(self, parent, text, image=image) return item - + def BuildTreeImageList(self): imgList = wx.ImageList(16, 16) for png in _demoPngs: imgList.Add(images.catalog[png].GetBitmap()) - + # add the image for modified demos. imgList.Add(images.catalog["custom"].GetBitmap()) self.AssignImageList(imgList) - def GetItemIdentity(self, item): - return self.GetPyData(item) - def Freeze(self): - if 'wxMSW' in wx.PlatformInfo: - return super(wxPythonDemoTree, self).Freeze() - - def Thaw(self): - if 'wxMSW' in wx.PlatformInfo: - return super(wxPythonDemoTree, self).Thaw() + def GetItemIdentity(self, item): + return self.GetItemData(item) + #--------------------------------------------------------------------------- @@ -2934,9 +2930,9 @@ class MyApp(wx.App, wx.lib.mixins.inspection.InspectionMixin): # For debugging #self.SetAssertMode(wx.PYAPP_ASSERT_DIALOG|wx.PYAPP_ASSERT_EXCEPTION) - wx.SystemOptions.SetOptionInt("mac.window-plain-transition", 1) + wx.SystemOptions.SetOption("mac.window-plain-transition", 1) self.SetAppName("wxPyDemo") - + # Create and show the splash screen. It will then create and # show the main frame when it is time to do so. Normally when # using a SplashScreen you would create it, show it and then @@ -3006,4 +3002,4 @@ if __name__ == '__main__': main() #---------------------------------------------------------------------------- - + diff --git a/demo/Mask.py b/demo/Mask.py index 01d773f3..42592f34 100644 --- a/demo/Mask.py +++ b/demo/Mask.py @@ -28,7 +28,7 @@ if 'mac-cg' in wx.PlatformInfo: ('wx.COPY', wx.COPY), ('wx.INVERT', wx.INVERT), ('wx.XOR', wx.XOR), - ] + ] import images @@ -118,9 +118,9 @@ def runTest(frame, nb, log): overview = """\ -This class encapsulates a monochrome mask bitmap, where the masked area is black -and the unmasked area is white. When associated with a bitmap and drawn in a device -context, the unmasked area of the bitmap will be drawn, and the masked area will +This class encapsulates a monochrome mask bitmap, where the masked area is black +and the unmasked area is white. When associated with a bitmap and drawn in a device +context, the unmasked area of the bitmap will be drawn, and the masked area will not be drawn. This example shows not only how to create a Mask, but the effects of the Device diff --git a/demo/MaskedEditControls.py b/demo/MaskedEditControls.py index 5923db9b..c6033209 100644 --- a/demo/MaskedEditControls.py +++ b/demo/MaskedEditControls.py @@ -218,7 +218,7 @@ has a legal range specified. ("Integer (signed)", "#{6}", "", 'F-_', "", '','', ' 0 '), ("Integer (unsigned)\n(1-399)","######", "", 'F_', "", (1,399),'', '1 '), ("Float (signed)", "#{6}.#{9}", "", 'F-_R', "", '','', '000000.000000000'), - ("Date (MDY) + Time", "##/##/#### ##:##:## AM", 'BCDEFGHIJKLMNOQRSTUVWXYZ','DF!',"", '','', wx.DateTime_Now().Format("%m/%d/%Y %I:%M:%S %p")), + ("Date (MDY) + Time", "##/##/#### ##:##:## AM", 'BCDEFGHIJKLMNOQRSTUVWXYZ','DF!',"", '','', wx.DateTime.Now().Format("%m/%d/%Y %I:%M:%S %p")), ] self.layoutGeneralTable( controls, grid ) diff --git a/demo/MediaCtrl.py b/demo/MediaCtrl.py index 539a3c40..6a85b78f 100644 --- a/demo/MediaCtrl.py +++ b/demo/MediaCtrl.py @@ -37,7 +37,6 @@ class TestPanel(wx.Panel): szBackend=backend) if not ok: raise NotImplementedError - self.mc.PostCreate(self.mc) except NotImplementedError: self.Destroy() raise diff --git a/demo/Menu.py b/demo/Menu.py index 2e97d754..a031dc0a 100644 --- a/demo/Menu.py +++ b/demo/Menu.py @@ -43,7 +43,7 @@ check the source for this sample to see how to implement them. submenu.Append(2031,"Lanthanium") submenu.Append(2032,"Cerium") submenu.Append(2033,"Praseodymium") - menu2.AppendMenu(203, "Lanthanides", submenu) + menu2.Append(203, "Lanthanides", submenu) # Append 2nd menu menuBar.Append(menu2, "&Elements") @@ -65,10 +65,23 @@ check the source for this sample to see how to implement them. menuBar.Append(menu4, "Chec&k") menu5 = wx.Menu() - # Show how to put an icon in the menu + # Show how to put an icon in the menu item item = wx.MenuItem(menu5, 500, "&Smile!\tCtrl+S", "This one has an icon") item.SetBitmap(images.Smiles.GetBitmap()) - menu5.AppendItem(item) + menu5.Append(item) + + menuitemwithbmp = wx.MenuItem(menu5, wx.ID_ANY, "Submenu with Bitmap") + # Show how to change the background colour of the menu item + menuitemwithbmp.SetBackgroundColour(wx.YELLOW) + # Show how to change the menu item's text colour + menuitemwithbmp.SetTextColour(wx.BLUE) + # Show how to change the menu item's font + menuitemwithbmp.SetFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, '')) + submenu = wx.Menu(style=wx.MENU_TEAROFF) + submenu.Append(wx.MenuItem(menu5, wx.ID_ANY, "Woot!")) + menuitemwithbmp.SetBitmap(images.book.GetBitmap()) + menuitemwithbmp.SetSubMenu(submenu) + menu5.Append(menuitemwithbmp) # Shortcuts menu5.Append(501, "Interesting thing\tCtrl+A", "Note the shortcut!") @@ -78,7 +91,7 @@ check the source for this sample to see how to implement them. menu5.Append(503, "remove the submenu") menu6 = wx.Menu() menu6.Append(601, "Submenu Item") - menu5.AppendMenu(504, "submenu", menu6) + menu5.Append(504, "submenu", menu6) menu5.Append(505, "remove this menu") menu5.Append(506, "this is updated") menu5.Append(507, "insert after this...") @@ -131,7 +144,7 @@ check the source for this sample to see how to implement them. help = item.GetHelp() # but in this case just call Skip so the default is done - event.Skip() + event.Skip() def Menu101(self, event): @@ -198,10 +211,10 @@ check the source for this sample to see how to implement them. #menu.Remove(504) # this also works - menu.RemoveItem(mb.FindItemById(504)) + menu.RemoveItem(mb.FindItemById(504)) - # This doesn't work, as expected since submenuItem is not on menu - #menu.RemoveItem(submenuItem) + # This doesn't work, as expected since submenuItem is not on menu + #menu.RemoveItem(submenuItem) def TestRemove2(self, evt): @@ -265,29 +278,29 @@ def runTest(frame, nb, log): overview = """\ A demo of using wx.MenuBar and wx.Menu in various ways. -A menu is a popup (or pull down) list of items, one of which may be selected -before the menu goes away (clicking elsewhere dismisses the menu). Menus may be +A menu is a popup (or pull down) list of items, one of which may be selected +before the menu goes away (clicking elsewhere dismisses the menu). Menus may be used to construct either menu bars or popup menus. -A menu item has an integer ID associated with it which can be used to identify -the selection, or to change the menu item in some way. A menu item with a special -identifier -1 is a separator item and doesn't have an associated command but just +A menu item has an integer ID associated with it which can be used to identify +the selection, or to change the menu item in some way. A menu item with a special +identifier -1 is a separator item and doesn't have an associated command but just makes a separator line appear in the menu. -Menu items may be either normal items, check items or radio items. Normal items -don't have any special properties while the check items have a boolean flag associated -to them and they show a checkmark in the menu when the flag is set. wxWindows -automatically toggles the flag value when the item is clicked and its value may -be retrieved using either IsChecked method of wx.Menu or wx.MenuBar itself or by +Menu items may be either normal items, check items or radio items. Normal items +don't have any special properties while the check items have a boolean flag associated +to them and they show a checkmark in the menu when the flag is set. wxWindows +automatically toggles the flag value when the item is clicked and its value may +be retrieved using either IsChecked method of wx.Menu or wx.MenuBar itself or by using wxEvent.IsChecked when you get the menu notification for the item in question. -The radio items are similar to the check items except that all the other items -in the same radio group are unchecked when a radio item is checked. The radio group -is formed by a contiguous range of radio items, i.e. it starts at the first item of -this kind and ends with the first item of a different kind (or the end of the menu). -Notice that because the radio groups are defined in terms of the item positions -inserting or removing the items in the menu containing the radio items risks to not -work correctly. Finally note that the radio items are only supported under Windows +The radio items are similar to the check items except that all the other items +in the same radio group are unchecked when a radio item is checked. The radio group +is formed by a contiguous range of radio items, i.e. it starts at the first item of +this kind and ends with the first item of a different kind (or the end of the menu). +Notice that because the radio groups are defined in terms of the item positions +inserting or removing the items in the menu containing the radio items risks to not +work correctly. Finally note that the radio items are only supported under Windows and GTK+ currently. """ diff --git a/demo/MimeTypesManager.py b/demo/MimeTypesManager.py index b4d9f048..776619ee 100644 --- a/demo/MimeTypesManager.py +++ b/demo/MimeTypesManager.py @@ -6,8 +6,8 @@ # .wdr-derived demo # # Created: 12/31/03 -# RCS-ID: $Id$ -# Copyright: +# RCS-ID: $Id: MimeTypesManager.py 71035 2012-03-28 19:16:31Z RD $ +# Copyright: # Licence: wxWindows license #---------------------------------------------------------------------- # @@ -28,18 +28,18 @@ if 'unicode' in wx.PlatformInfo: class MimeTypesDemoPanel(wx.Panel): def __init__(self, parent, log): - + self.log = log - + wx.Panel.__init__(self, parent, -1) # This will be used for all of the labels that follow (bold label) bfont = self.GetFont() bfont.SetWeight(wx.BOLD) - + # Contains everything tsizer = wx.BoxSizer(wx.VERTICAL) - + # Contains upper controls usizer = wx.BoxSizer(wx.HORIZONTAL) @@ -159,7 +159,7 @@ class MimeTypesDemoPanel(wx.Panel): # multi-line) so the sizer can then expand it to whatever # space is available self.allcommands.SetSize((-1, 20)) - + llsizer.Add(self.allcommands, (7, 1), (1, 3), wx.ALL | wx.GROW | wx.ALIGN_CENTER, 2) # Tell the sizer to expand this row as needed @@ -169,7 +169,7 @@ class MimeTypesDemoPanel(wx.Panel): #---------------------------------------------------------------------------- lrsizer = wx.BoxSizer(wx.VERTICAL) - + #------- List box with known MIME types t = wx.StaticText(self, -1, 'Known MIME types') @@ -194,13 +194,13 @@ class MimeTypesDemoPanel(wx.Panel): self.SetSizer(tsizer) tsizer.Fit(self) - + # Populate the Known MIME types list with what is in the database try: mtypes = wx.TheMimeTypesManager.EnumAllFileTypes() except wx.PyAssertionError: mtypes = [] - + # TODO: On wxMac, EnumAllFileTypes produces tons of dupes, which # causes quirky behavior because the list control doesn't expect # dupes, and simply wastes space. So remove the dupes for now, @@ -213,7 +213,7 @@ class MimeTypesDemoPanel(wx.Panel): if mimes: mimes.sort() self.mimelist.AppendItems(mimes) - + # Do a lookup of *.wav for a starting position self.OnLookup() @@ -238,7 +238,7 @@ class MimeTypesDemoPanel(wx.Panel): if fileType: if self.mimelist.FindString(txt) != -1: self.mimelist.SetSelection(self.mimelist.FindString(txt)) - + # Must be an extension lookup else: fileType = wx.TheMimeTypesManager.GetFileTypeFromExtension(txt) @@ -274,7 +274,7 @@ class MimeTypesDemoPanel(wx.Panel): self.icon.SetIcon(icon) else: bmp = images.NoIcon.GetBitmap() - self.icon.SetBitmap(bmp) + self.icon.SetBitmap(bmp) self.iconsource.SetValue(file) self.iconoffset.SetValue(convert(idx)) @@ -309,14 +309,14 @@ class MimeTypesDemoPanel(wx.Panel): #------- All commands all = ft.GetAllCommands(filename, mime) - + if all is None: self.allcommands.SetValue("") else: verbs, commands = all text = pprint.pformat(map(None, verbs, commands)) self.allcommands.SetValue(text) - + #---------------------------------------------------------------------- @@ -328,16 +328,16 @@ def runTest(frame, nb, log): overview = """\ -The wx.MimeTypesManager class allows the application to retrieve the -information about all known MIME types from a system-specific location and the -filename extensions to the MIME types and vice versa. After initialization the -methods GetFileTypeFromMimeType() and GetFileTypeFromExtension() -may be called: they will return a wx.FileType object which may be further +The wx.MimeTypesManager class allows the application to retrieve the +information about all known MIME types from a system-specific location and the +filename extensions to the MIME types and vice versa. After initialization the +methods GetFileTypeFromMimeType() and GetFileTypeFromExtension() +may be called: they will return a wx.FileType object which may be further queried for file description, icon and other attributes. A global instance of wx.MimeTypesManager is always available as -wx.TheMimeTypesManager. It is recommended to use this instance instead -of creating your own because gathering MIME information may take quite a long +wx.TheMimeTypesManager. It is recommended to use this instance instead +of creating your own because gathering MIME information may take quite a long on Unix systems. This demo shows how to use wx.TheMimeTypesManager to list all known MIME types diff --git a/demo/MiniFrame.py b/demo/MiniFrame.py index 2bea751f..305289f1 100644 --- a/demo/MiniFrame.py +++ b/demo/MiniFrame.py @@ -5,7 +5,7 @@ import wx class MyMiniFrame(wx.MiniFrame): def __init__( self, parent, title, pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.DEFAULT_FRAME_STYLE + style=wx.DEFAULT_FRAME_STYLE ): wx.MiniFrame.__init__(self, parent, -1, title, pos, size, style) @@ -20,7 +20,7 @@ class MyMiniFrame(wx.MiniFrame): self.Close(True) def OnCloseWindow(self, event): - print "OnCloseWindow" + # print("OnCloseWindow") self.Destroy() #--------------------------------------------------------------------------- @@ -36,12 +36,12 @@ class TestPanel(wx.Panel): def OnButton(self, evt): win = MyMiniFrame(self, "This is a wx.MiniFrame", - style=wx.DEFAULT_FRAME_STYLE | wx.TINY_CAPTION_HORIZ) + style=wx.DEFAULT_FRAME_STYLE | wx.TINY_CAPTION) win.SetSize((200, 200)) win.CenterOnParent(wx.BOTH) win.Show(True) - + #--------------------------------------------------------------------------- @@ -54,8 +54,8 @@ def runTest(frame, nb, log): overview = """\ -A MiniFrame is a Frame with a small title bar. It is suitable for floating -toolbars that must not take up too much screen area. In other respects, it's the +A MiniFrame is a Frame with a small title bar. It is suitable for floating +toolbars that must not take up too much screen area. In other respects, it's the same as a wx.Frame. """ diff --git a/demo/MultiSash.py b/demo/MultiSash.py index 6af173b5..d02d6eca 100644 --- a/demo/MultiSash.py +++ b/demo/MultiSash.py @@ -1,7 +1,7 @@ -import wx -import wx.lib.multisash as sash -import wx.stc as stc +import wx +import wx.lib.multisash as sash +import wx.stc as stc #--------------------------------------------------------------------------- @@ -31,7 +31,7 @@ class TestWindow(stc.StyledTextCtrl): # shared document reference doc = None - + def __init__(self, parent): stc.StyledTextCtrl.__init__(self, parent, -1, style=wx.NO_BORDER) self.SetMarginWidth(1,0) @@ -43,21 +43,21 @@ class TestWindow(stc.StyledTextCtrl): self.StyleSetFont( stc.STC_STYLE_DEFAULT, - wx.Font(fSize, wx.MODERN, wx.NORMAL, wx.NORMAL) + wx.Font(fSize, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) ) - if self.doc: - self.SetDocPointer(self.doc) - else: - self.SetText(sampleText) - TestWindow.doc = self.GetDocPointer() - + ## if self.doc: + ## self.SetDocPointer(self.doc) + ## else: + self.SetText(sampleText) + TestWindow.doc = self.GetDocPointer() + def ShutDownDemo(self): # Reset doc reference in case this demo is run again TestWindow.doc = None - + #--------------------------------------------------------------------------- diff --git a/demo/Notebook.py b/demo/Notebook.py index 8eeaca7c..cd95b30a 100644 --- a/demo/Notebook.py +++ b/demo/Notebook.py @@ -15,7 +15,7 @@ class TestNB(wx.Notebook): def __init__(self, parent, id, log): wx.Notebook.__init__(self, parent, id, size=(21,21), style= wx.BK_DEFAULT - #wx.BK_TOP + #wx.BK_TOP #wx.BK_BOTTOM #wx.BK_LEFT #wx.BK_RIGHT @@ -62,10 +62,10 @@ class TestNB(wx.Notebook): win = self.makeColorPanel(wx.CYAN) self.AddPage(win, "Cyan") - win = self.makeColorPanel(wx.NamedColour('Midnight Blue')) + win = self.makeColorPanel(wx.Colour('Midnight Blue')) self.AddPage(win, "Midnight Blue") - win = self.makeColorPanel(wx.NamedColour('Indian Red')) + win = self.makeColorPanel(wx.Colour('Indian Red')) self.AddPage(win, "Indian Red") self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged) diff --git a/demo/OwnerDrawnComboBox.py b/demo/OwnerDrawnComboBox.py index ada91fb1..75a7c925 100644 --- a/demo/OwnerDrawnComboBox.py +++ b/demo/OwnerDrawnComboBox.py @@ -1,13 +1,13 @@ import wx -import wx.combo +import wx.adv #---------------------------------------------------------------------- # This ComboBox class graphically displays the various pen styles that # are available, making it easy for the user to choose the style they # want. -class PenStyleComboBox(wx.combo.OwnerDrawnComboBox): +class PenStyleComboBox(wx.adv.OwnerDrawnComboBox): # Overridden from OwnerDrawnComboBox, called to draw each # item in the list @@ -42,11 +42,11 @@ class PenStyleComboBox(wx.combo.OwnerDrawnComboBox): penStyle = wx.HORIZONTAL_HATCH elif item == 11: penStyle = wx.VERTICAL_HATCH - + pen = wx.Pen(dc.GetTextForeground(), 3, penStyle) dc.SetPen(pen) - if flags & wx.combo.ODCB_PAINTING_CONTROL: + if flags & wx.adv.ODCB_PAINTING_CONTROL: # for painting the control itself dc.DrawLine( r.x+5, r.y+r.height/2, r.x+r.width - 5, r.y+r.height/2 ) @@ -58,22 +58,22 @@ class PenStyleComboBox(wx.combo.OwnerDrawnComboBox): ) dc.DrawLine( r.x+5, r.y+((r.height/4)*3)+1, r.x+r.width - 5, r.y+((r.height/4)*3)+1 ) - + # Overridden from OwnerDrawnComboBox, called for drawing the # background area of each item. def OnDrawBackground(self, dc, rect, item, flags): # If the item is selected, or its item # iseven, or we are painting the # combo control itself, then use the default rendering. - if (item & 1 == 0 or flags & (wx.combo.ODCB_PAINTING_CONTROL | - wx.combo.ODCB_PAINTING_SELECTED)): - wx.combo.OwnerDrawnComboBox.OnDrawBackground(self, dc, rect, item, flags) + if (item & 1 == 0 or flags & (wx.adv.ODCB_PAINTING_CONTROL | + wx.adv.ODCB_PAINTING_SELECTED)): + wx.adv.OwnerDrawnComboBox.OnDrawBackground(self, dc, rect, item, flags) return # Otherwise, draw every other background with different colour. bgCol = wx.Colour(240,240,250) dc.SetBrush(wx.Brush(bgCol)) dc.SetPen(wx.Pen(bgCol)) - dc.DrawRectangleRect(rect); + dc.DrawRectangle(rect); @@ -90,9 +90,9 @@ class PenStyleComboBox(wx.combo.OwnerDrawnComboBox): # -1 for default/undetermined def OnMeasureItemWidth(self, item): return -1; # default - will be measured from text width - - + + #---------------------------------------------------------------------- diff --git a/demo/PenAndBrushStyles.py b/demo/PenAndBrushStyles.py index b66dc816..1fc73fb8 100644 --- a/demo/PenAndBrushStyles.py +++ b/demo/PenAndBrushStyles.py @@ -14,15 +14,13 @@ brush_styles = ["wx.SOLID", "wx.TRANSPARENT", "wx.STIPPLE", "wx.BDIAGONAL_HATCH" "wx.HORIZONTAL_HATCH", "wx.VERTICAL_HATCH"] - - class BasePanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER|wx.WANTS_CHARS) self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) - self.Bind(wx.EVT_SIZE, self.OnSize) + self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_PAINT, self.OnPaint) @@ -36,7 +34,7 @@ class PenPanel(BasePanel): def __init__(self, parent, pen_name): BasePanel.__init__(self, parent) self.pen_name = pen_name - + def OnPaint(self, event): width, height = self.GetClientSize() @@ -49,8 +47,8 @@ class PenPanel(BasePanel): font.MakeSmaller() dc.SetFont(font) w, labelHeight = dc.GetTextExtent('Wy') - - name = self.pen_name + + name = self.pen_name if "STIPPLE" in name: bmp = images.Smiles.GetBitmap() @@ -67,7 +65,7 @@ class PenPanel(BasePanel): # dash values represent units on, off, on. off... pen.SetDashes([2, 5, 2, 2]) name += " ([2, 5, 2, 2])" - + dc.SetTextForeground(wx.BLACK) dc.DrawText(name, 1, 1) @@ -80,7 +78,7 @@ class BrushPanel(BasePanel): def __init__(self, parent, brush_name): BasePanel.__init__(self, parent) self.brush_name = brush_name - + def OnPaint(self, event): width, height = self.GetClientSize() @@ -94,16 +92,16 @@ class BrushPanel(BasePanel): dc.SetFont(font) w, labelHeight = dc.GetTextExtent('Wy') - dc.SetPen(wx.TRANSPARENT_PEN) + dc.SetPen(wx.TRANSPARENT_PEN) name = self.brush_name - + if "STIPPLE" in name: bmp = images.Smiles.GetBitmap() bmp.SetMask(None) - brush = wx.BrushFromBitmap(bmp) + brush = wx.Brush(bmp) else: brush = wx.Brush(wx.BLUE, eval(name)) - + dc.SetTextForeground(wx.BLACK) dc.DrawText(name, 1, 1) @@ -124,7 +122,7 @@ class TestPanel(wx.Panel): label1.SetFont(font) mainSizer.Add(label1, 0, wx.EXPAND|wx.ALL, 10) - + gs1 = wx.GridSizer(4, 4, 3, 3) # rows, cols, vgap, hgap for pen_name in pen_styles: @@ -137,7 +135,7 @@ class TestPanel(wx.Panel): label2.SetFont(font) mainSizer.Add(label2, 0, wx.EXPAND|wx.ALL, 10) - + gs2 = wx.GridSizer(3, 3, 3, 3) # rows, cols, vgap, hgap for brush_name in brush_styles: @@ -145,9 +143,9 @@ class TestPanel(wx.Panel): gs2.Add(small, 0, wx.EXPAND) mainSizer.Add(gs2, 1, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, 10) - + self.SetSizer(mainSizer) - + diff --git a/demo/Pickers.py b/demo/Pickers.py index 1291533a..e6dfaffb 100644 --- a/demo/Pickers.py +++ b/demo/Pickers.py @@ -14,9 +14,9 @@ class TestPanel(wx.Panel): title.SetForegroundColour("navy") box.Add(title, 0, wx.ALIGN_CENTER|wx.ALL, 5) #print title.GetBestSize(), title.GetMinSize(), title.GetSize() - + box.Add(wx.StaticLine(self), 0, wx.EXPAND) - + fgs = wx.FlexGridSizer(cols=4, hgap=5, vgap=5) fgs.AddGrowableCol(3) fgs.Add((10,10)) # spacer @@ -32,7 +32,7 @@ class TestPanel(wx.Panel): cp1 = wx.ColourPickerCtrl(self) fgs.Add(cp1, 0, wx.ALIGN_CENTER) fgs.Add((10,10)) # spacer - cp2 = wx.ColourPickerCtrl(self, style=wx.CLRP_USE_TEXTCTRL) + cp2 = wx.ColourPickerCtrl(self, style=wx.CLRP_USE_TEXTCTRL) cp2.SetTextCtrlProportion(5) fgs.Add(cp2, 0, wx.EXPAND) fgs.Add(wx.StaticText(self, -1, " with label:"), 0, wx.ALIGN_CENTER_VERTICAL) @@ -86,9 +86,9 @@ class TestPanel(wx.Panel): self.log.write("You chose: %s\n" % repr(evt.GetPath())) def OnPickFont(self, evt): - font = evt.GetFont() + font = evt.GetFont() self.log.write("You chose: %s\n" % font.GetNativeFontInfoUserDesc()) - + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/PlateButton.py b/demo/PlateButton.py index 33c10de0..7aeabb48 100644 --- a/demo/PlateButton.py +++ b/demo/PlateButton.py @@ -230,7 +230,7 @@ class GradientPanel(wx.Panel): def OnPaint(self, evt): dc = wx.PaintDC(self) gc = wx.GraphicsContext.Create(dc) - col1 = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW) + col1 = wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DSHADOW) col2 = platebtn.AdjustColour(col1, -90) col1 = platebtn.AdjustColour(col1, 90) rect = self.GetClientRect() diff --git a/demo/PopupControl.py b/demo/PopupControl.py index d5b17f56..1e3afd09 100644 --- a/demo/PopupControl.py +++ b/demo/PopupControl.py @@ -1,14 +1,15 @@ -import wx -import wx.lib.popupctl as pop -import wx.calendar as cal +import wx +import wx.adv +import wx.lib.popupctl as pop +from wx.adv import CalendarCtrl class TestDateControl(pop.PopupControl): def __init__(self,*_args,**_kwargs): pop.PopupControl.__init__(self, *_args, **_kwargs) self.win = wx.Window(self,-1,pos = (0,0),style = 0) - self.cal = cal.CalendarCtrl(self.win,-1,pos = (0,0)) + self.cal = CalendarCtrl(self.win,-1,pos = (0,0)) bz = self.cal.GetBestSize() self.win.SetSize(bz) @@ -18,7 +19,7 @@ class TestDateControl(pop.PopupControl): self.SetPopupContent(self.win) # Event registration for date selection - self.cal.Bind(cal.EVT_CALENDAR, self.OnCalSelected) + self.cal.Bind(wx.adv.EVT_CALENDAR, self.OnCalSelected) # Method called when a day is selected in the calendar @@ -52,7 +53,7 @@ class TestDateControl(pop.PopupControl): if d > 0 and d < 31: if m >= 0 and m < 12: if y > 1000: - self.cal.SetDate(wx.DateTimeFromDMY(d,m,y)) + self.cal.SetDate(wx.DateTime.FromDMY(d,m,y)) didSet = True if not didSet: diff --git a/demo/PopupMenu.py b/demo/PopupMenu.py index 7d6a9059..2c6ca10f 100644 --- a/demo/PopupMenu.py +++ b/demo/PopupMenu.py @@ -52,7 +52,7 @@ class TestPanel(wx.Panel): # # Yet another anternate way to do IDs. Some prefer them up top to # avoid clutter, some prefer them close to the object of interest - # for clarity. + # for clarity. if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() self.popupID2 = wx.NewId() @@ -80,7 +80,7 @@ class TestPanel(wx.Panel): item = wx.MenuItem(menu, self.popupID1,"One") bmp = images.Smiles.GetBitmap() item.SetBitmap(bmp) - menu.AppendItem(item) + menu.Append(item) # add some other items menu.Append(self.popupID2, "Two") menu.Append(self.popupID3, "Three") @@ -91,7 +91,7 @@ class TestPanel(wx.Panel): sm = wx.Menu() sm.Append(self.popupID8, "sub item 1") sm.Append(self.popupID9, "sub item 1") - menu.AppendMenu(self.popupID7, "Test Submenu", sm) + menu.Append(self.popupID7, "Test Submenu", sm) # Popup the menu. If an item is selected then its handler @@ -129,8 +129,6 @@ class TestPanel(wx.Panel): - - #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/PrintDialog.py b/demo/PrintDialog.py index e86dddf2..caceebed 100644 --- a/demo/PrintDialog.py +++ b/demo/PrintDialog.py @@ -20,7 +20,7 @@ class TestPanel(wx.Panel): data.EnablePageNumbers(True) data.SetMinPage(1) data.SetMaxPage(5) - data.SetAllPages(True) + # data.SetAllPages(True) dlg = wx.PrintDialog(self, data) @@ -31,7 +31,6 @@ class TestPanel(wx.Panel): dlg.Destroy() - #--------------------------------------------------------------------------- @@ -43,7 +42,7 @@ def runTest(frame, nb, log): overview = """\ -This class represents the print and print setup common dialogs. You may obtain +This class represents the print and print setup common dialogs. You may obtain a wx.PrinterDC device context from a successfully dismissed print dialog. User information is stored in a wx.PrintDialogData object that is passed to the diff --git a/demo/PrintFramework.py b/demo/PrintFramework.py index 4cc1c940..3bcc3532 100644 --- a/demo/PrintFramework.py +++ b/demo/PrintFramework.py @@ -61,7 +61,7 @@ class MyPrintout(wx.Printout): maxY = maxY + (2 * marginY) # Get the size of the DC in pixels - (w, h) = dc.GetSizeTuple() + (w, h) = dc.GetSize() # Calculate a suitable scaling factor scaleX = float(w) / maxX @@ -98,7 +98,7 @@ class TestPrintPanel(wx.Panel): self.printData = wx.PrintData() self.printData.SetPaperId(wx.PAPER_LETTER) self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER) - + self.box = wx.BoxSizer(wx.VERTICAL) self.canvas = ScrolledWindow.MyCanvas(self) self.box.Add(self.canvas, 1, wx.GROW) @@ -122,11 +122,10 @@ class TestPrintPanel(wx.Panel): self.SetSizer(self.box) - def OnPageSetup(self, evt): psdd = wx.PageSetupDialogData(self.printData) psdd.EnablePrinter(True) - psdd.CalculatePaperSizeFromId() + # psdd.CalculatePaperSizeFromId() dlg = wx.PageSetupDialog(self, psdd) dlg.ShowModal() @@ -143,7 +142,7 @@ class TestPrintPanel(wx.Panel): printout2 = MyPrintout(self.canvas, self.log) self.preview = wx.PrintPreview(printout, printout2, data) - if not self.preview.Ok(): + if not self.preview.IsOk(): self.log.WriteText("Houston, we have a problem...\n") return @@ -154,8 +153,6 @@ class TestPrintPanel(wx.Panel): pfrm.SetSize(self.frame.GetSize()) pfrm.Show(True) - - def OnDoPrint(self, event): pdd = wx.PrintDialogData(self.printData) pdd.SetToPage(2) @@ -180,8 +177,6 @@ def runTest(frame, nb, log): - - overview = """\ @@ -193,26 +188,26 @@ setup dialog.

Classes demonstrated here:

diff --git a/demo/RawBitmapAccess.py b/demo/RawBitmapAccess.py index b4b6b768..843d5abc 100644 --- a/demo/RawBitmapAccess.py +++ b/demo/RawBitmapAccess.py @@ -53,9 +53,9 @@ class TestPanel(wx.Panel): log.write("Timing...\n") num = 100 tm = t.timeit(num) - log.write("%d passes in %f seconds == %f seconds per pass " % + log.write("%d passes in %f seconds == %f seconds per pass " % (num, tm, tm/num)) - + if not USE_NUMPY: log.write("using raw access\n") self.redBmp = self.MakeBitmap(178, 34, 34) @@ -85,7 +85,7 @@ class TestPanel(wx.Panel): def MakeBitmap(self, red, green, blue, alpha=128): # Create the bitmap that we will stuff pixel values into using # the raw bitmap access classes. - bmp = wx.EmptyBitmap(DIM, DIM, 32) + bmp = wx.Bitmap(DIM, DIM, 32) # Create an object that facilitates access to the bitmap's # pixel buffer @@ -126,7 +126,7 @@ class TestPanel(wx.Panel): pixels.Set(red, green, blue, wx.ALPHA_OPAQUE) pixels.MoveTo(pixelData, DIM-1, y) pixels.Set(red, green, blue, wx.ALPHA_OPAQUE) - + return bmp @@ -153,9 +153,9 @@ class TestPanel(wx.Panel): # finally, use the array to create a bitmap bmp = wx.BitmapFromBufferRGBA(DIM, DIM, arr) return bmp - - - + + + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/ResizeWidget.py b/demo/ResizeWidget.py index 2f824230..2f44b613 100644 --- a/demo/ResizeWidget.py +++ b/demo/ResizeWidget.py @@ -12,7 +12,7 @@ class TestPanel(wx.Panel): rw1 = rw.ResizeWidget(self) rw2 = rw.ResizeWidget(self) self.rw2 = rw2 - + # This one we will reparent to the ResizeWidget... tst = wx.Panel(self) tst.SetBackgroundColour('pink') @@ -20,11 +20,11 @@ class TestPanel(wx.Panel): tst.SetMinSize((80,35)) tst.SetMaxSize((200,100)) rw1.SetManagedChild(tst) - + # This one we will create as a child of the resizer to start with lb = wx.ListBox(rw2, size=(100,70), choices="zero one two three four five six seven eight nine".split()) - + # now make a sizer with a bunch of other widgets fgs = wx.FlexGridSizer(cols=4, vgap=5, hgap=5) for i in range(16): @@ -36,21 +36,20 @@ class TestPanel(wx.Panel): fgs.Add(wx.Button(self)) self.Bind(wx.EVT_BUTTON, self.OnButton) - + self.Sizer = wx.BoxSizer() self.Sizer.Add(fgs, 0, wx.ALL, 10) self.Bind(rw.EVT_RW_LAYOUT_NEEDED, self.OnLayoutNeeded) - + def OnLayoutNeeded(self, evt): self.Layout() - def OnButton(self, evt): self.rw2.EnableResize(not self.rw2.IsResizeEnabled()) - + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/SashWindow.py b/demo/SashWindow.py index 72b6357c..c703e37d 100644 --- a/demo/SashWindow.py +++ b/demo/SashWindow.py @@ -1,5 +1,6 @@ -import wx +import wx +import wx.adv #--------------------------------------------------------------------------- @@ -13,46 +14,46 @@ class TestSashWindow(wx.Panel): # Create some layout windows # A window like a toolbar - topwin = wx.SashLayoutWindow( + topwin = wx.adv.SashLayoutWindow( self, -1, wx.DefaultPosition, (200, 30), - wx.NO_BORDER|wx.SW_3D + wx.NO_BORDER|wx.adv.SW_3D ) topwin.SetDefaultSize((1000, 30)) - topwin.SetOrientation(wx.LAYOUT_HORIZONTAL) - topwin.SetAlignment(wx.LAYOUT_TOP) + topwin.SetOrientation(wx.adv.LAYOUT_HORIZONTAL) + topwin.SetAlignment(wx.adv.LAYOUT_TOP) topwin.SetBackgroundColour(wx.Colour(255, 0, 0)) - topwin.SetSashVisible(wx.SASH_BOTTOM, True) + topwin.SetSashVisible(wx.adv.SASH_BOTTOM, True) self.topWindow = topwin winids.append(topwin.GetId()) # A window like a statusbar - bottomwin = wx.SashLayoutWindow( + bottomwin = wx.adv.SashLayoutWindow( self, -1, wx.DefaultPosition, (200, 30), - wx.NO_BORDER|wx.SW_3D + wx.NO_BORDER|wx.adv.SW_3D ) bottomwin.SetDefaultSize((1000, 30)) - bottomwin.SetOrientation(wx.LAYOUT_HORIZONTAL) - bottomwin.SetAlignment(wx.LAYOUT_BOTTOM) + bottomwin.SetOrientation(wx.adv.LAYOUT_HORIZONTAL) + bottomwin.SetAlignment(wx.adv.LAYOUT_BOTTOM) bottomwin.SetBackgroundColour(wx.Colour(0, 0, 255)) - bottomwin.SetSashVisible(wx.SASH_TOP, True) + bottomwin.SetSashVisible(wx.adv.SASH_TOP, True) self.bottomWindow = bottomwin winids.append(bottomwin.GetId()) # A window to the left of the client window - leftwin1 = wx.SashLayoutWindow( + leftwin1 = wx.adv.SashLayoutWindow( self, -1, wx.DefaultPosition, (200, 30), - wx.NO_BORDER|wx.SW_3D + wx.NO_BORDER|wx.adv.SW_3D ) leftwin1.SetDefaultSize((120, 1000)) - leftwin1.SetOrientation(wx.LAYOUT_VERTICAL) - leftwin1.SetAlignment(wx.LAYOUT_LEFT) + leftwin1.SetOrientation(wx.adv.LAYOUT_VERTICAL) + leftwin1.SetAlignment(wx.adv.LAYOUT_LEFT) leftwin1.SetBackgroundColour(wx.Colour(0, 255, 0)) - leftwin1.SetSashVisible(wx.SASH_RIGHT, True) + leftwin1.SetSashVisible(wx.adv.SASH_RIGHT, True) leftwin1.SetExtraBorderSize(10) textWindow = wx.TextCtrl( leftwin1, -1, "", wx.DefaultPosition, wx.DefaultSize, @@ -66,16 +67,16 @@ class TestSashWindow(wx.Panel): # Another window to the left of the client window - leftwin2 = wx.SashLayoutWindow( + leftwin2 = wx.adv.SashLayoutWindow( self, -1, wx.DefaultPosition, (200, 30), - wx.NO_BORDER|wx.SW_3D + wx.NO_BORDER|wx.adv.SW_3D ) leftwin2.SetDefaultSize((120, 1000)) - leftwin2.SetOrientation(wx.LAYOUT_VERTICAL) - leftwin2.SetAlignment(wx.LAYOUT_LEFT) + leftwin2.SetOrientation(wx.adv.LAYOUT_VERTICAL) + leftwin2.SetAlignment(wx.adv.LAYOUT_LEFT) leftwin2.SetBackgroundColour(wx.Colour(0, 255, 255)) - leftwin2.SetSashVisible(wx.SASH_RIGHT, True) + leftwin2.SetSashVisible(wx.adv.SASH_RIGHT, True) self.leftWindow2 = leftwin2 winids.append(leftwin2.GetId()) @@ -84,7 +85,7 @@ class TestSashWindow(wx.Panel): self.remainingSpace = wx.Panel(self, -1, style=wx.SUNKEN_BORDER) self.Bind( - wx.EVT_SASH_DRAGGED_RANGE, self.OnSashDrag, + wx.adv.EVT_SASH_DRAGGED_RANGE, self.OnSashDrag, id=min(winids), id2=max(winids) ) @@ -92,7 +93,7 @@ class TestSashWindow(wx.Panel): def OnSashDrag(self, event): - if event.GetDragStatus() == wx.SASH_STATUS_OUT_OF_RANGE: + if event.GetDragStatus() == wx.adv.SASH_STATUS_OUT_OF_RANGE: self.log.write('drag is out of range') return @@ -115,11 +116,11 @@ class TestSashWindow(wx.Panel): self.log.write('bottomwin received drag event') self.bottomWindow.SetDefaultSize((1000, event.GetDragRect().height)) - wx.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace) + wx.adv.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace) self.remainingSpace.Refresh() def OnSize(self, event): - wx.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace) + wx.adv.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace) #--------------------------------------------------------------------------- @@ -131,8 +132,8 @@ def runTest(frame, nb, log): overview = """\ -wx.SashLayoutWindow responds to OnCalculateLayout events generated by -wxLayoutAlgorithm. It allows the application to use simple accessors to +wx.adv.SashLayoutWindow responds to OnCalculateLayout events generated by +wx.adv.LayoutAlgorithm. It allows the application to use simple accessors to specify how the window should be laid out, rather than having to respond to events. The fact that the class derives from wx.SashWindow allows sashes to be used if required, to allow the windows to be user-resizable. diff --git a/demo/ScrolledWindow.py b/demo/ScrolledWindow.py index fcd1d74f..8ec46b2b 100644 --- a/demo/ScrolledWindow.py +++ b/demo/ScrolledWindow.py @@ -21,7 +21,7 @@ class MyCanvas(wx.ScrolledWindow): self.drawing = False self.SetBackgroundColour("WHITE") - self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL)) + self.SetCursor(wx.Cursor(wx.CURSOR_PENCIL)) bmp = images.Test2.GetBitmap() mask = wx.Mask(bmp, wx.BLUE) bmp.SetMask(mask) @@ -32,7 +32,7 @@ class MyCanvas(wx.ScrolledWindow): if BUFFERED: # Initialize the buffer bitmap. No real DC is needed at this point. - self.buffer = wx.EmptyBitmap(self.maxWidth, self.maxHeight) + self.buffer = wx.Bitmap(self.maxWidth, self.maxHeight) dc = wx.BufferedDC(None, self.buffer) dc.SetBackground(wx.Brush(self.GetBackgroundColour())) dc.Clear() @@ -69,7 +69,7 @@ class MyCanvas(wx.ScrolledWindow): def DoDrawing(self, dc, printing=False): - dc.BeginDrawing() + # dc.BeginDrawing() dc.SetPen(wx.Pen('RED')) dc.DrawRectangle(5, 5, 50, 50) @@ -142,8 +142,7 @@ class MyCanvas(wx.ScrolledWindow): dc.GradientFillConcentric((20, 325, 50, 50), "red", "blue", (25,25)) self.DrawSavedLines(dc) - dc.EndDrawing() - + # dc.EndDrawing() def DrawSavedLines(self, dc): dc.SetPen(wx.Pen('MEDIUM FOREST GREEN', 4)) diff --git a/demo/ShapedWindow.py b/demo/ShapedWindow.py index 80983b1e..5f179d3e 100644 --- a/demo/ShapedWindow.py +++ b/demo/ShapedWindow.py @@ -18,12 +18,12 @@ class TestFrame(wx.Frame): self.hasShape = False self.delta = (0,0) - self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) - self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) - self.Bind(wx.EVT_MOTION, self.OnMouseMove) - self.Bind(wx.EVT_RIGHT_UP, self.OnExit) - self.Bind(wx.EVT_PAINT, self.OnPaint) + self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) + self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) + self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) + self.Bind(wx.EVT_MOTION, self.OnMouseMove) + self.Bind(wx.EVT_RIGHT_UP, self.OnExit) + self.Bind(wx.EVT_PAINT, self.OnPaint) self.bmp = images.Vippi.GetBitmap() w, h = self.bmp.GetWidth(), self.bmp.GetHeight() @@ -31,8 +31,8 @@ class TestFrame(wx.Frame): if wx.Platform != "__WXMAC__": # wxMac clips the tooltip to the window shape, YUCK!!! - self.SetToolTipString("Right-click to close the window\n" - "Double-click the image to set/unset the window shape") + self.SetToolTip("Right-click to close the window\n" + "Double-click the image to set/unset the window shape") if wx.Platform == "__WXGTK__": # wxGTK requires that the window be created before you can @@ -49,10 +49,9 @@ class TestFrame(wx.Frame): def SetWindowShape(self, *evt): # Use the bitmap's mask to determine the region - r = wx.RegionFromBitmap(self.bmp) + r = wx.Region(self.bmp) self.hasShape = self.SetShape(r) - def OnDoubleClick(self, evt): if self.hasShape: self.SetShape(wx.Region()) @@ -60,7 +59,6 @@ class TestFrame(wx.Frame): else: self.SetWindowShape() - def OnPaint(self, evt): dc = wx.PaintDC(self) dc.DrawBitmap(self.bmp, 0,0, True) @@ -68,7 +66,6 @@ class TestFrame(wx.Frame): def OnExit(self, evt): self.Close() - def OnLeftDown(self, evt): self.CaptureMouse() x, y = self.ClientToScreen(evt.GetPosition()) @@ -77,12 +74,10 @@ class TestFrame(wx.Frame): dy = y - originy self.delta = ((dx, dy)) - def OnLeftUp(self, evt): if self.HasCapture(): self.ReleaseMouse() - def OnMouseMove(self, evt): if evt.Dragging() and evt.LeftIsDown(): x, y = self.ClientToScreen(evt.GetPosition()) diff --git a/demo/Sizers.py b/demo/Sizers.py index 1d79096a..2482b8b6 100644 --- a/demo/Sizers.py +++ b/demo/Sizers.py @@ -15,13 +15,13 @@ import wx #---------------------------------------------------------------------- -class SampleWindow(wx.PyWindow): +class SampleWindow(wx.Window): """ A simple window that is used as sizer items in the tests below to show how the various sizers work. """ def __init__(self, parent, text, pos=wx.DefaultPosition, size=wx.DefaultSize): - wx.PyWindow.__init__(self, parent, -1, + wx.Window.__init__(self, parent, -1, #style=wx.RAISED_BORDER #style=wx.SUNKEN_BORDER style=wx.SIMPLE_BORDER @@ -32,11 +32,11 @@ class SampleWindow(wx.PyWindow): else: self.bestsize = (80,25) self.SetSize(self.GetBestSize()) - + self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_LEFT_UP, self.OnCloseParent) - + def OnPaint(self, evt): sz = self.GetSize() @@ -51,11 +51,11 @@ class SampleWindow(wx.PyWindow): def OnCloseParent(self, evt): p = wx.GetTopLevelParent(self) if p: - p.Close() + p.Close() def DoGetBestSize(self): return self.bestsize - + #---------------------------------------------------------------------- @@ -539,7 +539,7 @@ class TestFrame(wx.Frame): self.Fit() def OnCloseWindow(self, event): - self.MakeModal(False) + # self.MakeModal(False) self.Destroy() @@ -550,28 +550,36 @@ class TestSelectionPanel(wx.Panel): wx.Panel.__init__(self, parent) self.list = wx.ListBox(self, -1, - wx.DLG_PNT(self, 10, 10), wx.DLG_SZE(self, 100, 100), + (-1, -1), (-1, -1), []) + self.list.Fit() self.Bind(wx.EVT_LISTBOX, self.OnSelect, self.list) self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnDClick, self.list) - wx.Button(self, -1, "Try it!", wx.DLG_PNT(self, 120, 10)).SetDefault() - self.Bind(wx.EVT_BUTTON, self.OnDClick) + btn = wx.Button(self, -1, "Try it!", (120, 10)) + btn.Bind(wx.EVT_BUTTON, self.OnDClick) self.text = wx.TextCtrl(self, -1, "", - wx.DLG_PNT(self, 10, 115), - wx.DLG_SZE(self, 200, 50), + (10, 115), + (200, 50), wx.TE_MULTILINE | wx.TE_READONLY) for item in theTests: self.list.Append(item[0]) + hsizer = wx.BoxSizer(wx.HORIZONTAL) + hsizer.Add(self.list, 1, wx.ALL, 8) + hsizer.Add(btn, 0, wx.ALL, 8) + vsizer = wx.BoxSizer(wx.VERTICAL) + vsizer.Add(hsizer) + vsizer.Add(self.text, 1, wx.EXPAND | wx.ALL, 8) + self.SetSizerAndFit(vsizer) + def OnSelect(self, event): pos = self.list.GetSelection() self.text.SetValue(theTests[pos][2]) - def OnDClick(self, event): pos = self.list.GetSelection() title = theTests[pos][0] diff --git a/demo/Slider.py b/demo/Slider.py index 7be4bdb5..2b829c0e 100644 --- a/demo/Slider.py +++ b/demo/Slider.py @@ -12,11 +12,11 @@ class TestPanel(wx.Panel): wx.StaticText(self, -1, "This is a wx.Slider.", (45, 15)) slider = wx.Slider( - self, 100, 25, 1, 100, (30, 60), (250, -1), - wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS + self, 100, 25, 1, 100, (30, 60), (250, -1), + wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS ) - slider.SetTickFreq(5, 1) + slider.SetTickFreq(5) @@ -32,10 +32,10 @@ def runTest(frame, nb, log): overview = """\ -A slider is a control with a handle which can be pulled back and forth to +A slider is a control with a handle which can be pulled back and forth to change the value. -In Windows versions below Windows 95, a scrollbar is used to simulate the slider. +In Windows versions below Windows 95, a scrollbar is used to simulate the slider. In Windows 95, the track bar control is used. """ diff --git a/demo/Sound.py b/demo/Sound.py index 2a2977f7..13c6e976 100644 --- a/demo/Sound.py +++ b/demo/Sound.py @@ -1,6 +1,6 @@ import wx - +import wx.adv from Main import opj #---------------------------------------------------------------------- @@ -22,9 +22,9 @@ class TestPanel(wx.Panel): def OnButton1(self, evt): try: - sound = wx.Sound(opj('data/anykey.wav')) + sound = wx.adv.Sound(opj('data/anykey.wav')) self.log.write("before Play...\n") - sound.Play(wx.SOUND_SYNC) + sound.Play(wx.adv.SOUND_SYNC) self.log.write("...after Play\n") except NotImplementedError, v: wx.MessageBox(str(v), "Exception Message") @@ -33,16 +33,16 @@ class TestPanel(wx.Panel): def OnButton2(self, evt): try: if True: - sound = wx.Sound(opj('data/plan.wav')) + sound = wx.adv.Sound(opj('data/plan.wav')) else: # sounds can also be loaded from a buffer object data = open(opj('data/plan.wav'), 'rb').read() sound = wx.SoundFromData(data) self.log.write("before Play...\n") - sound.Play(wx.SOUND_ASYNC) + sound.Play(wx.adv.SOUND_ASYNC) self.sound = sound # save a reference (This shoudln't be needed, but there seems to be a bug...) - wx.YieldIfNeeded() + # wx.YieldIfNeeded() self.log.write("...after Play\n") except NotImplementedError, v: wx.MessageBox(str(v), "Exception Message") @@ -52,14 +52,14 @@ class TestPanel(wx.Panel): dlg = wx.FileDialog(wx.GetTopLevelParent(self), "Choose a sound file", wildcard="WAV files (*.wav)|*.wav", - style=wx.OPEN) + style=wx.FD_OPEN) if dlg.ShowModal() == wx.ID_OK: try: - #sound = wx.Sound(dlg.GetPath(), wx.SOUND_SYNC) + #sound = wx.adv.Sound(dlg.GetPath(), wx.SOUND_SYNC) #sound.Play() # another way to do it. - wx.Sound.PlaySound(dlg.GetPath(), wx.SOUND_SYNC) + wx.adv.Sound.PlaySound(dlg.GetPath(), wx.adv.SOUND_SYNC) except NotImplementedError, v: wx.MessageBox(str(v), "Exception Message") diff --git a/demo/StatusBar.py b/demo/StatusBar.py index 3f218842..0e379ed5 100644 --- a/demo/StatusBar.py +++ b/demo/StatusBar.py @@ -2,6 +2,8 @@ import time import wx +RELATIVEWIDTHS = False + #--------------------------------------------------------------------------- class CustomStatusBar(wx.StatusBar): @@ -10,8 +12,11 @@ class CustomStatusBar(wx.StatusBar): # This status bar has three fields self.SetFieldsCount(3) - # Sets the three fields to be relative widths to each other. - self.SetStatusWidths([-2, -1, -2]) + if RELATIVEWIDTHS: + # Sets the three fields to be relative widths to each other. + self.SetStatusWidths([-2, -1, -2]) + else: + self.SetStatusWidths([-2, 90, 140]) self.log = log self.sizeChanged = False self.Bind(wx.EVT_SIZE, self.OnSize) @@ -28,8 +33,7 @@ class CustomStatusBar(wx.StatusBar): # set the initial position of the checkbox self.Reposition() - # We're going to use a timer to drive a 'clock' in the last - # field. + # We're going to use a timer to drive a 'clock' in the last field. self.timer = wx.PyTimer(self.Notify) self.timer.Start(1000) self.Notify() @@ -70,14 +74,14 @@ class CustomStatusBar(wx.StatusBar): # reposition the checkbox def Reposition(self): - rect = self.GetFieldRect(1) - rect.x += 1 - rect.y += 1 - self.cb.SetRect(rect) + # sw0 = self.GetStatusWidth(0) + sw1 = self.GetStatusWidth(1) + sw2 = self.GetStatusWidth(2) + sz = self.GetSize() + self.cb.SetPosition((sz[0] - sw2 - sw1 - 25, 4)) self.sizeChanged = False - class TestCustomStatusBar(wx.Frame): def __init__(self, parent, log): wx.Frame.__init__(self, parent, -1, 'Test Custom StatusBar') @@ -124,7 +128,7 @@ overview = """\ A status bar is a narrow window that can be placed along the bottom of a frame to give small amounts of status information. It can contain one or more fields, one or more of which can be variable length -according to the size of the window. +according to the size of the window. This example demonstrates how to create a custom status bar with actual gadgets embedded in it. In this case, the first field is just plain text, diff --git a/demo/StyledTextCtrl_1.py b/demo/StyledTextCtrl_1.py index c0c19a59..ef27532b 100644 --- a/demo/StyledTextCtrl_1.py +++ b/demo/StyledTextCtrl_1.py @@ -1,13 +1,13 @@ -# +# # 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net) # # o wx.TheClipboard.Flush() generates a warning on program exit. -# +# -import wx -import wx.stc as stc +import wx +import wx.stc as stc -import images +import images #---------------------------------------------------------------------- @@ -174,7 +174,7 @@ def runTest(frame, nb, log): #ed.StyleClearAll() #ed.SetScrollWidth(800) #ed.SetWrapMode(True) - #ed.SetUseAntiAliasing(False) + #ed.SetUseAntiAliasing(False) #ed.SetViewEOL(True) #ed.CmdKeyClear(stc.STC_KEY_BACK, @@ -185,19 +185,19 @@ def runTest(frame, nb, log): ed.SetText(demoText) - if wx.USE_UNICODE: - import codecs - decode = codecs.lookup("utf-8")[1] + # if wx.USE_UNICODE: + import codecs + decode = codecs.lookup("utf-8")[1] - ed.GotoPos(ed.GetLength()) - ed.AddText("\n\nwx.StyledTextCtrl can also do Unicode:\n") - uniline = ed.GetCurrentLine() - unitext, l = decode('\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd - ' - '\xd0\xbb\xd1\x83\xd1\x87\xd1\x88\xd0\xb8\xd0\xb9 ' - '\xd1\x8f\xd0\xb7\xd1\x8b\xd0\xba \xd0\xbf\xd1\x80\xd0\xbe\xd0\xb3\xd1\x80\xd0\xb0\xd0\xbc\xd0\xbc\xd0\xb8\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x8f!\n\n') - ed.AddText('\tRussian: ') - ed.AddText(unitext) - ed.GotoPos(0) + ed.GotoPos(ed.GetLength()) + ed.AddText("\n\nwx.StyledTextCtrl can also do Unicode:\n") + uniline = ed.GetCurrentLine() + unitext, l = decode('\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd - ' + '\xd0\xbb\xd1\x83\xd1\x87\xd1\x88\xd0\xb8\xd0\xb9 ' + '\xd1\x8f\xd0\xb7\xd1\x8b\xd0\xba \xd0\xbf\xd1\x80\xd0\xbe\xd0\xb3\xd1\x80\xd0\xb0\xd0\xbc\xd0\xbc\xd0\xb8\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x8f!\n\n') + ed.AddText('\tRussian: ') + ed.AddText(unitext) + ed.GotoPos(0) #else: # #ed.StyleSetFontEncoding(stc.STC_STYLE_DEFAULT, wx.FONTENCODING_KOI8) # #text = u'\u041f\u0438\u0442\u043e\u043d - \u043b\u0443\u0447\u0448\u0438\u0439 \u044f\u0437\u044b\u043a \n\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f!' @@ -207,7 +207,7 @@ def runTest(frame, nb, log): # #text = text.encode('big5') # ed.GotoPos(ed.GetLength()) # ed.AddText('\n\n' + text) - + ed.EmptyUndoBuffer() # make some styles @@ -217,8 +217,7 @@ def runTest(frame, nb, log): ed.StyleSetSpec(2, "face:%s,italic,fore:#FF0000,size:%d" % (face2, pb)) ed.StyleSetSpec(3, "face:%s,bold,size:%d" % (face2, pb)) ed.StyleSetSpec(4, "face:%s,size:%d" % (face1, pb-1)) - ed.StyleSetSpec(5, "back:#FFF0F0") - + # Now set some text to those styles... Normally this would be # done in an event handler that happens when text needs displayed. ed.StartStyling(98, 0xff) @@ -253,7 +252,7 @@ def runTest(frame, nb, log): ed.MarkerAdd(20, 0) - # and an indicator or two + # and finally, an indicator or two ed.IndicatorSetStyle(0, stc.STC_INDIC_SQUIGGLE) ed.IndicatorSetForeground(0, wx.RED) ed.IndicatorSetStyle(1, stc.STC_INDIC_DIAGONAL) @@ -266,34 +265,30 @@ def runTest(frame, nb, log): ed.SetStyling(8, stc.STC_INDIC1_MASK) ed.SetStyling(10, stc.STC_INDIC2_MASK | stc.STC_INDIC1_MASK) - # add some annotations - ed.AnnotationSetText(23, "\nThis is an annotaion, it is not part of \nthe document's text.\n") - ed.AnnotationSetVisible(stc.STC_ANNOTATION_BOXED) - ed.AnnotationSetStyle(23, 5) # line number, style number # some test stuff... if debug: - print "GetTextLength(): ", ed.GetTextLength(), len(ed.GetText()) - print "GetText(): ", repr(ed.GetText()) - print - print "GetStyledText(98, 104): ", repr(ed.GetStyledText(98, 104)), len(ed.GetStyledText(98, 104)) - print - print "GetCurLine(): ", repr(ed.GetCurLine()) + print("GetTextLength(): ", ed.GetTextLength(), len(ed.GetText())) + print("GetText(): ", repr(ed.GetText())) + print() + print("GetStyledText(98, 104): ", repr(ed.GetStyledText(98, 104)), len(ed.GetStyledText(98, 104))) + print() + print("GetCurLine(): ", repr(ed.GetCurLine())) ed.GotoPos(5) - print "GetCurLine(): ", repr(ed.GetCurLine()) - print - print "GetLine(1): ", repr(ed.GetLine(1)) - print + print("GetCurLine(): ", repr(ed.GetCurLine())) + print() + print("GetLine(1): ", repr(ed.GetLine(1))) + print() ed.SetSelection(25, 35) - print "GetSelectedText(): ", repr(ed.GetSelectedText()) - print "GetTextRange(25, 35): ", repr(ed.GetTextRange(25, 35)) - print "FindText(0, max, 'indicators'): ", - print ed.FindText(0, ed.GetTextLength(), "indicators") - if wx.USE_UNICODE: - end = ed.GetLength() - start = ed.PositionFromLine(uniline) - print "GetTextRange(%d, %d): " % (start, end), - print repr(ed.GetTextRange(start, end)) + print("GetSelectedText(): ", repr(ed.GetSelectedText())) + print("GetTextRange(25, 35): ", repr(ed.GetTextRange(25, 35))) + print("FindText(0, max, 'indicators'): ",) + print(ed.FindText(0, ed.GetTextLength(), "indicators") + # if wx.USE_UNICODE: + end = ed.GetLength() + start = ed.PositionFromLine(uniline) + print("GetTextRange(%d, %d): " % (start, end),) + print(repr(ed.GetTextRange(start, end))) wx.CallAfter(ed.GotoPos, 0) diff --git a/demo/StyledTextCtrl_2.py b/demo/StyledTextCtrl_2.py index 7926e07c..1bf3bac6 100644 --- a/demo/StyledTextCtrl_2.py +++ b/demo/StyledTextCtrl_2.py @@ -49,7 +49,7 @@ else: class PythonSTC(stc.StyledTextCtrl): fold_symbols = 2 - + def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0): @@ -70,7 +70,7 @@ class PythonSTC(stc.StyledTextCtrl): #self.SetViewEOL(True) #self.SetEOLMode(stc.STC_EOL_CRLF) #self.SetUseAntiAliasing(True) - + self.SetEdgeMode(stc.STC_EDGE_BACKGROUND) self.SetEdgeColumn(78) @@ -90,7 +90,7 @@ class PythonSTC(stc.StyledTextCtrl): self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black") self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black") self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black") - + elif self.fold_symbols == 1: # Plus for contracted folders, minus for expanded self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_MINUS, "white", "black") @@ -142,7 +142,7 @@ class PythonSTC(stc.StyledTextCtrl): self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold") # Python styles - # Default + # Default self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces) # Comments self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces) @@ -176,9 +176,9 @@ class PythonSTC(stc.StyledTextCtrl): # register some images for use in the AutoComplete box. self.RegisterImage(1, images.Smiles.GetBitmap()) - self.RegisterImage(2, + self.RegisterImage(2, wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16,16))) - self.RegisterImage(3, + self.RegisterImage(3, wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16,16))) diff --git a/demo/SystemSettings.py b/demo/SystemSettings.py index d3861bb4..52372bfd 100644 --- a/demo/SystemSettings.py +++ b/demo/SystemSettings.py @@ -17,8 +17,8 @@ element sizes.

""" __author__ = "Cody Precord " -__svnid__ = "$Id$" -__revision__ = "$Revision$" +__svnid__ = "$Id: SystemSettings.py 64744 2010-06-25 21:59:08Z RD $" +__revision__ = "$Revision: 64744 $" #-----------------------------------------------------------------------------# # Imports @@ -59,9 +59,9 @@ class TestPanel(wx.Panel): #---------------------------------------------------------------------- -class SysPanelBase(wx.PyPanel): +class SysPanelBase(wx.Panel): def __init__(self, parent, log): - wx.PyPanel.__init__(self, parent)#, size=(500, 500)) + wx.Panel.__init__(self, parent)#, size=(500, 500)) # Attributes self.log = log @@ -95,7 +95,7 @@ class SysPanelBase(wx.PyPanel): dc.SetFont(self.GetFont()) dc.SetBrush(wx.WHITE_BRUSH) dc.Clear() - dc.DrawRectangleRect(self.GetClientRect()) + dc.DrawRectangle(self.GetClientRect()) dc.SetPen(wx.BLACK_PEN) dc.SetTextForeground(wx.BLACK) @@ -158,10 +158,15 @@ class SysFontPanel(SysPanelBase): # Attributes: self._maxw = 0 - self._vals = ['SYS_ANSI_FIXED_FONT', 'SYS_ANSI_VAR_FONT', - 'SYS_DEFAULT_GUI_FONT', 'SYS_DEVICE_DEFAULT_FONT', - 'SYS_ICONTITLE_FONT', 'SYS_OEM_FIXED_FONT', - 'SYS_SYSTEM_FIXED_FONT', 'SYS_SYSTEM_FONT'] + self._vals = ['SYS_ANSI_FIXED_FONT', + 'SYS_ANSI_VAR_FONT', + 'SYS_DEFAULT_GUI_FONT', + 'SYS_DEVICE_DEFAULT_FONT', + # 'SYS_ICONTITLE_FONT', + 'SYS_OEM_FIXED_FONT', + # 'SYS_SYSTEM_FIXED_FONT', + 'SYS_SYSTEM_FONT' + ] def OnPaint(self, evt): diff --git a/demo/TablePrint.py b/demo/TablePrint.py index 73818dda..1c9098b8 100644 --- a/demo/TablePrint.py +++ b/demo/TablePrint.py @@ -69,14 +69,14 @@ class TablePanel(wx.Panel): prt.SetLandscape() prt.SetColumnLineSize(2, 3) - prt.SetColumnLineColour(3, wx.NamedColour('RED')) + prt.SetColumnLineColour(3, wx.RED) prt.SetRowLineSize(1, 3) - prt.SetRowLineColour(5, wx.NamedColour('RED')) + prt.SetRowLineColour(5, wx.RED) prt.SetHeader("wx.Windows Applications") prt.SetFooter() - prt.SetFooter("Date: ", type = "Date", align=wx.ALIGN_RIGHT, indent = -1, colour = wx.NamedColour('RED')) + prt.SetFooter("Date: ", type = "Date", align=wx.ALIGN_RIGHT, indent = -1, colour = wx.RED) prt.Preview() def PreviewNarrow(self): @@ -93,21 +93,21 @@ class TablePanel(wx.Panel): prt.set_column = [ 1, 1, 1, 1, 2] prt.label = new_header prt.SetColAlignment(1, wx.ALIGN_CENTRE) - prt.SetColBackgroundColour(0, wx.NamedColour('RED')) - prt.SetColTextColour(0, wx.NamedColour('WHITE')) - prt.SetCellColour(4, 0, wx.NamedColour('LIGHT BLUE')) - prt.SetCellColour(4, 1, wx.NamedColour('LIGHT BLUE')) - prt.SetCellColour(17, 1, wx.NamedColour('LIGHT BLUE')) + prt.SetColBackgroundColour(0, wx.RED) + prt.SetColTextColour(0, wx.WHITE) + prt.SetCellColour(4, 0, wx.Colour('LIGHT BLUE')) + prt.SetCellColour(4, 1, wx.Colour('LIGHT BLUE')) + prt.SetCellColour(17, 1, wx.Colour('LIGHT BLUE')) - prt.SetColBackgroundColour(2, wx.NamedColour('LIGHT BLUE')) - prt.SetCellText(4, 2, wx.NamedColour('RED')) + prt.SetColBackgroundColour(2, wx.Colour('LIGHT BLUE')) + prt.SetCellText(4, 2, wx.RED) - prt.SetColTextColour(3, wx.NamedColour('RED')) - prt.label_font_colour = wx.NamedColour('WHITE') - prt.SetHeader("wxWindows Applications", colour = wx.NamedColour('RED')) + prt.SetColTextColour(3, wx.RED) + prt.label_font_colour = wx.WHITE + prt.SetHeader("wxWindows Applications", colour = wx.RED) - prt.SetHeader("Printed: ", type = "Date & Time", align=wx.ALIGN_RIGHT, indent = -1, colour = wx.NamedColour('BLUE')) - prt.SetFooter("Page No", colour = wx.NamedColour('RED'), type ="Num") + prt.SetHeader("Printed: ", type = "Date & Time", align=wx.ALIGN_RIGHT, indent = -1, colour = wx.BLUE) + prt.SetFooter("Page No", colour = wx.RED, type ="Num") prt.Preview() def OnPreviewMatrix(self): diff --git a/demo/Ticker.py b/demo/Ticker.py index 8eb01f78..12ad5e5e 100644 --- a/demo/Ticker.py +++ b/demo/Ticker.py @@ -1,5 +1,5 @@ -import wx +import wx from wx.lib.ticker import Ticker import wx.lib.colourselect as csel #for easy color selection @@ -9,9 +9,9 @@ class TestPanel(wx.Panel): def __init__(self, parent, log): self.log = log wx.Panel.__init__(self, parent, -1) - + self.ticker = Ticker(self) - + # Controls for ...controlling... the ticker. self.txt = wx.TextCtrl(self, value="I am a scrolling ticker!!!!", size=(200,-1)) wx.CallAfter(self.txt.SetInsertionPoint, 0) @@ -33,37 +33,37 @@ class TestPanel(wx.Panel): ppf = wx.Slider(self, value=self.ticker.GetPPF(), minValue=1, maxValue=10, size=(150,-1), style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS) - + # Do layout sz = wx.FlexGridSizer(cols=2, hgap=4, vgap=4) - + sz.Add(txtl, flag=wx.ALIGN_CENTER_VERTICAL) sz.Add(self.txt, flag=wx.ALIGN_CENTER_VERTICAL) - + sz.Add(fgl, flag=wx.ALIGN_CENTER_VERTICAL) sz.Add(fgb, flag=wx.ALIGN_CENTER_VERTICAL) - + sz.Add(bgl, flag=wx.ALIGN_CENTER_VERTICAL) sz.Add(bgb, flag=wx.ALIGN_CENTER_VERTICAL) - + sz.Add(self.fontl, flag=wx.ALIGN_CENTER_VERTICAL) sz.Add(fontb, flag=wx.ALIGN_CENTER_VERTICAL) - + sz.Add(self.dirl, flag=wx.ALIGN_CENTER_VERTICAL) sz.Add(dirb, flag=wx.ALIGN_CENTER_VERTICAL) - + sz.Add(fpsl, flag=wx.ALIGN_CENTER_VERTICAL) sz.Add(fps, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT) - + sz.Add(ppfl, flag=wx.ALIGN_CENTER_VERTICAL) sz.Add(ppf, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT) - + sz2 = wx.BoxSizer(wx.VERTICAL) sz2.Add(self.ticker, flag=wx.EXPAND|wx.ALL, border=5) sz2.Add(sz, flag=wx.EXPAND|wx.ALL, proportion=1, border=25) self.SetSizer(sz2) sz2.SetSizeHints(self) - + # Bind events self.Bind(wx.EVT_BUTTON, self.OnChangeTickDirection, dirb) self.Bind(wx.EVT_BUTTON, self.OnChangeTickFont, fontb) @@ -72,20 +72,19 @@ class TestPanel(wx.Panel): self.Bind(csel.EVT_COLOURSELECT, self.ChangeTickBGColor, bgb) self.Bind(wx.EVT_SCROLL, self.ChangeFPS, fps) self.Bind(wx.EVT_SCROLL, self.ChangePPF, ppf) - + # Set defaults self.SetTickDirection("rtl") self.SetTickFont(self.ticker.GetFont()) self.ticker.SetText(self.txt.GetValue()) - + def SetTickFont(self, font): """Sets ticker font, updates label""" self.ticker.SetFont(font) self.fontl.SetLabel("Font: %s"%(self.ticker.GetFont().GetFaceName())) self.Layout() - - + def OnChangeTickFont(self, evt): fd = wx.FontData() fd.EnableEffects(False) @@ -94,42 +93,38 @@ class TestPanel(wx.Panel): if dlg.ShowModal() == wx.ID_OK: data = dlg.GetFontData() self.SetTickFont(data.GetChosenFont()) - - + def SetTickDirection(self, dir): """Sets tick direction, updates label""" self.ticker.SetDirection(dir) self.dirl.SetLabel("Direction: %s"%(self.ticker.GetDirection())) - - + def OnChangeTickDirection(self, dir): if self.ticker.GetDirection() == "rtl": self.SetTickDirection("ltr") else: self.SetTickDirection("rtl") - - + def OnText(self, evt): """Live update of the ticker text""" self.ticker.SetText(self.txt.GetValue()) - + def ChangeTickFGColor(self, evt): self.ticker.SetForegroundColour(evt.GetValue()) - + def ChangeTickBGColor(self, evt): self.ticker.SetBackgroundColour(evt.GetValue()) - + def ChangeFPS(self, evt): self.ticker.SetFPS(evt.GetPosition()) - + def ChangePPF(self, evt): self.ticker.SetPPF(evt.GetPosition()) - def ShutdownDemo(self): self.ticker.Stop() - + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/TimeCtrl.py b/demo/TimeCtrl.py index a94bd24d..6574c68f 100644 --- a/demo/TimeCtrl.py +++ b/demo/TimeCtrl.py @@ -5,8 +5,8 @@ # import wx -import wx.lib.scrolledpanel as scrolled -import wx.lib.masked as masked +import wx.lib.scrolledpanel as scrolled +import wx.lib.masked as masked #---------------------------------------------------------------------- @@ -18,7 +18,7 @@ class TestPanel( scrolled.ScrolledPanel ): box_label = wx.StaticBox( self, -1, "Change Controls through API" ) buttonbox = wx.StaticBoxSizer( box_label, wx.HORIZONTAL ) - + text1 = wx.StaticText( self, -1, "12-hour format:") self.time12 = masked.TimeCtrl( self, -1, name="12 hour control" ) h = self.time12.GetSize().height @@ -73,7 +73,7 @@ class TestPanel( scrolled.ScrolledPanel ): radio_vbox.Add( self.radio24to12, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) radio_vbox.Add( self.radioWx, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) radio_vbox.Add( self.radioMx, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - + buttonbox.Add( buttonChange, 0, wx.ALIGN_CENTRE|wx.ALL, 5 ) buttonbox.Add( radio_vbox, 0, wx.ALIGN_CENTRE|wx.ALL, 5 ) @@ -168,7 +168,7 @@ class TestPanel( scrolled.ScrolledPanel ): self.time12.SetValue( self.time24.GetValue() ) elif self.radioWx.GetValue(): - now = wx.DateTime_Now() + now = wx.DateTime.Now() self.time12.SetValue( now ) # (demonstrates that G/SetValue returns/takes a wx.DateTime) self.time24.SetValue( self.time12.GetValue(as_wxDateTime=True) ) diff --git a/demo/ToolBar.py b/demo/ToolBar.py index 28f38905..bfe5b361 100644 --- a/demo/ToolBar.py +++ b/demo/ToolBar.py @@ -14,7 +14,7 @@ TBFLAGS = ( wx.TB_HORIZONTAL class TestSearchCtrl(wx.SearchCtrl): maxSearches = 5 - + def __init__(self, parent, id=-1, value="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, doSearch=None): @@ -31,13 +31,13 @@ class TestSearchCtrl(wx.SearchCtrl): self.searches.append(text) if len(self.searches) > self.maxSearches: del self.searches[0] - self.SetMenu(self.MakeMenu()) + self.SetMenu(self.MakeMenu()) self.SetValue("") def OnMenuItem(self, evt): text = self.searches[evt.GetId()-1] self.doSearch(text) - + def MakeMenu(self): menu = wx.Menu() item = menu.Append(-1, "Recent Searches") @@ -45,7 +45,6 @@ class TestSearchCtrl(wx.SearchCtrl): for idx, txt in enumerate(self.searches): menu.Append(1+idx, txt) return menu - class TestToolBar(wx.Frame): @@ -56,7 +55,7 @@ class TestToolBar(wx.Frame): self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) client = wx.Panel(self) - client.SetBackgroundColour(wx.NamedColour("WHITE")) + client.SetBackgroundColour(wx.WHITE) if FRAMETB: # Use the wxFrame internals to create the toolbar and @@ -79,7 +78,6 @@ class TestToolBar(wx.Frame): sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(tb, 0, wx.EXPAND) client.SetSizer(sizer) - log.write("Default toolbar tool size: %s\n" % tb.GetToolBitmapSize()) @@ -92,31 +90,31 @@ class TestToolBar(wx.Frame): paste_bmp= wx.ArtProvider.GetBitmap(wx.ART_PASTE, wx.ART_TOOLBAR, tsize) tb.SetToolBitmapSize(tsize) - - #tb.AddSimpleTool(10, new_bmp, "New", "Long help for 'New'") - tb.AddLabelTool(10, "New", new_bmp, shortHelp="New", longHelp="Long help for 'New'") + + #tb.AddTool(10, new_bmp, "New", "Long help for 'New'") + tb.AddTool(10, "New", new_bmp, wx.NullBitmap, wx.ITEM_NORMAL, "New", "Long help for 'New'", None) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=10) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=10) - #tb.AddSimpleTool(20, open_bmp, "Open", "Long help for 'Open'") - tb.AddLabelTool(20, "Open", open_bmp, shortHelp="Open", longHelp="Long help for 'Open'") + #tb.AddTool(20, open_bmp, "Open", "Long help for 'Open'") + tb.AddTool(20, "Open", open_bmp, wx.NullBitmap, wx.ITEM_NORMAL, "Open", "Long help for 'Open'", None) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=20) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=20) tb.AddSeparator() - tb.AddSimpleTool(30, copy_bmp, "Copy", "Long help for 'Copy'") + tb.AddTool(30, "Copy", copy_bmp, wx.NullBitmap, wx.ITEM_NORMAL, "Copy", "Long help for 'Copy'", None) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=30) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=30) - tb.AddSimpleTool(40, paste_bmp, "Paste", "Long help for 'Paste'") + tb.AddTool(40, "Paste", paste_bmp, wx.NullBitmap, wx.ITEM_NORMAL, "Paste", "Long help for 'Paste'", None) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=40) self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=40) tb.AddSeparator() #tool = tb.AddCheckTool(50, images.Tog1.GetBitmap(), shortHelp="Toggle this") - tool = tb.AddCheckLabelTool(50, "Checkable", images.Tog1.GetBitmap(), - shortHelp="Toggle this") + tool = tb.AddTool(50, "Checkable", images.Tog1.GetBitmap(), + shortHelp="Toggle this", kind=wx.ITEM_CHECK) self.Bind(wx.EVT_TOOL, self.OnToolClick, id=50) self.Bind(wx.EVT_TOOL_ENTER, self.OnToolEnter) @@ -147,7 +145,6 @@ class TestToolBar(wx.Frame): self.log.WriteText("DoSearch: %s\n" % text) # return true to tell the search ctrl to remember the text return True - def OnToolClick(self, event): self.log.WriteText("tool %s clicked\n" % event.GetId()) @@ -173,13 +170,11 @@ class TestToolBar(wx.Frame): self.timer.Start(2000) event.Skip() - def OnClearSB(self, event): # called for the timer event handler self.SetStatusText("") self.timer.Stop() self.timer = None - def OnCloseWindow(self, event): if self.timer is not None: self.timer.Stop() @@ -227,7 +222,7 @@ must be called to render it. wx.Toolbar events are also propogated as Menu events; this is especially handy when you have a menu bar that contains items that carry out the same function. For example, -it is not uncommon to have a little 'floppy' toolbar icon to 'save' the current file +it is not uncommon to have a little 'floppy' toolbar icon to 'save' the current file (whatever it is) as well as a FILE/SAVE menu item that does the same thing. In this case, both events can be captured and acted upon using the same event handler with no ill effects. @@ -235,7 +230,7 @@ with no ill effects. If there are cases where a toolbar icon should *not* be associated with a menu item, use a unique ID to trap it. -There are a number of ways to create a toolbar for a wx.Frame. wx.Frame.CreateToolBar() +There are a number of ways to create a toolbar for a wx.Frame. wx.Frame.CreateToolBar() does all the work except it adds no buttons at all unless you override the virtual method OnCreateToolBar(). On the other hand, you can just subclass wx.ToolBar and then use wx.Frame.SetToolBar() instead. diff --git a/demo/TreeCtrl.py b/demo/TreeCtrl.py index b00d22de..528ca905 100644 --- a/demo/TreeCtrl.py +++ b/demo/TreeCtrl.py @@ -38,9 +38,9 @@ class TestTreeCtrlPanel(wx.Panel): isz = (16,16) il = wx.ImageList(isz[0], isz[1]) - fldridx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz)) - fldropenidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_OTHER, isz)) - fileidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz)) + fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz)) + fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_OTHER, isz)) + fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz)) smileidx = il.Add(images.Smiles.GetBitmap()) self.tree.SetImageList(il) @@ -52,26 +52,26 @@ class TestTreeCtrlPanel(wx.Panel): # the item data. self.root = self.tree.AddRoot("The Root Item") - self.tree.SetPyData(self.root, None) + self.tree.SetItemData(self.root, None) self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded) for x in range(15): child = self.tree.AppendItem(self.root, "Item %d" % x) - self.tree.SetPyData(child, None) + self.tree.SetItemData(child, None) self.tree.SetItemImage(child, fldridx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(child, fldropenidx, wx.TreeItemIcon_Expanded) for y in range(5): last = self.tree.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y))) - self.tree.SetPyData(last, None) + self.tree.SetItemData(last, None) self.tree.SetItemImage(last, fldridx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(last, fldropenidx, wx.TreeItemIcon_Expanded) for z in range(5): item = self.tree.AppendItem(last, "item %d-%s-%d" % (x, chr(ord("a")+y), z)) - self.tree.SetPyData(item, None) + self.tree.SetItemData(item, None) self.tree.SetItemImage(item, fileidx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(item, smileidx, wx.TreeItemIcon_Selected) @@ -87,7 +87,6 @@ class TestTreeCtrlPanel(wx.Panel): self.tree.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.tree.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) - def OnRightDown(self, event): pt = event.GetPosition(); item, flags = self.tree.HitTest(pt) @@ -96,17 +95,14 @@ class TestTreeCtrlPanel(wx.Panel): (self.tree.GetItemText(item), type(item), item.__class__)) self.tree.SelectItem(item) - def OnRightUp(self, event): pt = event.GetPosition(); item, flags = self.tree.HitTest(pt) - if item: + if item: self.log.WriteText("OnRightUp: %s (manually starting label edit)\n" % self.tree.GetItemText(item)) self.tree.EditLabel(item) - - def OnBeginEdit(self, event): self.log.WriteText("OnBeginEdit\n") # show how to prevent edit... @@ -128,7 +124,6 @@ class TestTreeCtrlPanel(wx.Panel): event.Veto() - def OnEndEdit(self, event): self.log.WriteText("OnEndEdit: %s %s\n" % (event.IsEditCancelled(), event.GetLabel()) ) @@ -139,7 +134,6 @@ class TestTreeCtrlPanel(wx.Panel): event.Veto() return - def OnLeftDClick(self, event): pt = event.GetPosition(); item, flags = self.tree.HitTest(pt) @@ -150,11 +144,9 @@ class TestTreeCtrlPanel(wx.Panel): self.tree.SortChildren(parent) event.Skip() - def OnSize(self, event): - w,h = self.GetClientSizeTuple() - self.tree.SetDimensions(0, 0, w, h) - + w,h = self.GetClientSize() + self.tree.SetSize(0, 0, w, h) def OnItemExpanded(self, event): item = event.GetItem() @@ -177,7 +169,6 @@ class TestTreeCtrlPanel(wx.Panel): #print map(self.tree.GetItemText, items) event.Skip() - def OnActivate(self, event): if self.item: self.log.WriteText("OnActivate: %s\n" % self.tree.GetItemText(self.item)) @@ -192,18 +183,14 @@ def runTest(frame, nb, log): #--------------------------------------------------------------------------- - - - overview = """\ -A TreeCtrl presents information as a hierarchy, with items that may be -expanded to show further items. Items in a tree control are referenced by +A TreeCtrl presents information as a hierarchy, with items that may be +expanded to show further items. Items in a tree control are referenced by wx.TreeItemId handles. """ - if __name__ == '__main__': import sys,os import run diff --git a/demo/UIActionSimulator.py b/demo/UIActionSimulator.py index 55987977..a1513a71 100644 --- a/demo/UIActionSimulator.py +++ b/demo/UIActionSimulator.py @@ -24,13 +24,13 @@ class TestPanel(wx.Panel): self.recordBtn = buttons.GenToggleButton(self, -1, "Record") self.Bind(wx.EVT_BUTTON, self.OnToggleRecordKeys, self.recordBtn) - self.recordBtn.SetToolTipString( + self.recordBtn.SetToolTip( "Click this button and then type some keys in the\n" "textctrl. Click here again when done.") self.playbackKeysBtn = buttons.GenButton(self, -1, "Playback") self.Bind(wx.EVT_BUTTON, self.OnPlaybackKeys, self.playbackKeysBtn) - self.playbackKeysBtn.SetToolTipString( + self.playbackKeysBtn.SetToolTip( "Record some key events and then click here to\n" "replay the recorded events.") self.playbackKeysBtn.Disable() @@ -98,7 +98,7 @@ class TestPanel(wx.Panel): return evtInfo = ( evtType, evt.KeyCode, - evt.Modifiers, + evt.GetModifiers(), self.stopwatchKeys.Time(), ) self.keyEvents.append(evtInfo) diff --git a/demo/URLDragAndDrop.py b/demo/URLDragAndDrop.py index 68795f66..1065b0f0 100644 --- a/demo/URLDragAndDrop.py +++ b/demo/URLDragAndDrop.py @@ -3,9 +3,9 @@ import wx #---------------------------------------------------------------------- -class MyURLDropTarget(wx.PyDropTarget): +class MyURLDropTarget(wx.DropTarget): def __init__(self, window): - wx.PyDropTarget.__init__(self) + wx.DropTarget.__init__(self) self.window = window self.data = wx.URLDataObject(); @@ -94,7 +94,6 @@ class TestPanel(wx.Panel): dropSource.SetData(data) result = dropSource.DoDragDrop() - def OnStartDrag2(self, evt): if evt.Dragging(): url = self.dragText2.GetValue() diff --git a/demo/Unicode.py b/demo/Unicode.py index aa7373d5..42639501 100644 --- a/demo/Unicode.py +++ b/demo/Unicode.py @@ -47,34 +47,26 @@ class TestPanel(wx.Panel): box = wx.BoxSizer(wx.VERTICAL) - if not wx.USE_UNICODE: - self.AddLine(box) - self.AddText(box, "Sorry, this wxPython was not built with Unicode support.", - font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD)) - self.AddLine(box) + font = self.GetFont() + font.SetPointSize(14) + font.SetWeight(wx.BOLD) - else: - font = self.GetFont() - font.SetPointSize(14) - font.SetWeight(wx.BOLD) - - self.AddLine(box) - self.AddText(box, chi_uni[0], chi_uni[1], 'Chinese:', font) - self.AddLine(box) + self.AddLine(box) + self.AddText(box, chi_uni[0], chi_uni[1], 'Chinese:', font) + self.AddLine(box) - self.AddText(box, lt1_uni[0], lt1_uni[1], 'Lithuanian:', font) - self.AddLine(box) - self.AddText(box, lt2_uni[0], lt2_uni[1], 'Lithuanian:', font) - self.AddLine(box) + self.AddText(box, lt1_uni[0], lt1_uni[1], 'Lithuanian:', font) + self.AddLine(box) + self.AddText(box, lt2_uni[0], lt2_uni[1], 'Lithuanian:', font) + self.AddLine(box) - self.AddText(box, kor_uni[0], kor_uni[1], 'Korean:', font) - self.AddLine(box) - - self.AddText(box, bul_uni[0], bul_uni[1], 'Bulgarian:', font) - self.AddLine(box) - self.AddText(box, rus_uni[0], rus_uni[1], 'Russian:', font) - self.AddLine(box) + self.AddText(box, kor_uni[0], kor_uni[1], 'Korean:', font) + self.AddLine(box) + self.AddText(box, bul_uni[0], bul_uni[1], 'Bulgarian:', font) + self.AddLine(box) + self.AddText(box, rus_uni[0], rus_uni[1], 'Russian:', font) + self.AddLine(box) border = wx.BoxSizer(wx.VERTICAL) border.Add(box, 1, wx.EXPAND|wx.ALL, 10) @@ -123,15 +115,15 @@ This demo shows how Unicode can be used to support text in many different languages using one locale when Unicode is enabled.

So what is the difference between the ANSI and Unicode builds?

- -

If ANSI is used, Python strings (bytes) are always used, and you can only + +

If ANSI is used, Python strings (bytes) are always used, and you can only display strings that use either the ASCII encoding, or the system's default -encoding. Any attempt to display other strings will result in garbled +encoding. Any attempt to display other strings will result in garbled characters.

When unicode is enabled, then all functions and methods in wxPython -that return a wxString will return an Python unicode object, and parameters -that expect a wxString can accept either a Python string or unicode object. (NOTE: If you aren't familiar with the difference between Python +that return a wxString will return an Python unicode object, and parameters +that expect a wxString can accept either a Python string or unicode object. (NOTE: If you aren't familiar with the difference between Python strings and Unicode objects, you should view this Python Unicode Object introduction.) If a string object is passed then it will be decoded into unicode using the converter pointed to by wxConvCurrent, which will use the default diff --git a/demo/Validator.py b/demo/Validator.py index 9faf3f72..c4103fdd 100644 --- a/demo/Validator.py +++ b/demo/Validator.py @@ -7,19 +7,20 @@ import wx ALPHA_ONLY = 1 DIGIT_ONLY = 2 -class MyValidator(wx.PyValidator): +class MyValidator(wx.Validator): def __init__(self, flag=None, pyVar=None): - wx.PyValidator.__init__(self) + wx.Validator.__init__(self) self.flag = flag self.Bind(wx.EVT_CHAR, self.OnChar) + def Clone(self): return MyValidator(self.flag) def Validate(self, win): tc = self.GetWindow() val = tc.GetValue() - + if self.flag == ALPHA_ONLY: for x in val: if x not in string.letters: @@ -32,7 +33,6 @@ class MyValidator(wx.PyValidator): return True - def OnChar(self, event): key = event.GetKeyCode() @@ -48,7 +48,7 @@ class MyValidator(wx.PyValidator): event.Skip() return - if not wx.Validator_IsSilent(): + if not wx.Validator.IsSilent(): wx.Bell() # Returning without calling even.Skip eats the event before it @@ -102,15 +102,14 @@ class TestValidatorPanel(wx.Panel): #---------------------------------------------------------------------- -class TextObjectValidator(wx.PyValidator): +class TextObjectValidator(wx.Validator): """ This validator is used to ensure that the user has entered something into the text object editor dialog's text field. """ def __init__(self): """ Standard constructor. """ - wx.PyValidator.__init__(self) - + wx.Validator.__init__(self) def Clone(self): @@ -120,7 +119,6 @@ class TextObjectValidator(wx.PyValidator): """ return TextObjectValidator() - def Validate(self, win): """ Validate the contents of the given text control. """ @@ -135,11 +133,10 @@ class TextObjectValidator(wx.PyValidator): return False else: textCtrl.SetBackgroundColour( - wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) + wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)) textCtrl.Refresh() return True - def TransferToWindow(self): """ Transfer data from validator to window. @@ -148,7 +145,6 @@ class TextObjectValidator(wx.PyValidator): """ return True # Prevent wxDialog from complaining. - def TransferFromWindow(self): """ Transfer data from window to validator. @@ -216,7 +212,7 @@ def runTest(frame, nb, log): overview = """\ -wx.Validator is the base class for a family of validator classes that mediate +wx.Validator is the base class for a family of validator classes that mediate between a class of control, and application data.

A validator has three major roles: diff --git a/demo/WIPzChecklistPhoenixDemo.txt b/demo/WIPzChecklistPhoenixDemo.txt new file mode 100644 index 00000000..12d26e65 --- /dev/null +++ b/demo/WIPzChecklistPhoenixDemo.txt @@ -0,0 +1,779 @@ +__ __ _____ _____ +\ \ / /|_ _|| __ \ + \ \ /\ / / | | | |__) | ____ + \ \/ \/ / | | | ___/ |_ / + \ /\ / _| |_ | | / / + \/ \/ |_____||_| /___| +WIPz Phoenix Demos Checklist +""" +[X] Demo Works! Woot :) +[ ] Demo Still NEEDS work, has missing libs, other. :( +""" +When all done, this checklist.txt can be discarded. + +Frames and Dialogs Demos +======================== +[ ] AUI_DockingWindowMgr +[ ] AUI_MDI +[X] Dialog +[X] Frame +[X] MDIWindows +[X] MiniFrame +[X] Wizard + +Common Dialogs Demos +==================== +[X] AboutBox +[X] ColourDialog +[X] DirDialog +[X] FileDialog +[X] FindReplaceDialog +[X] FontDialog +[X] MessageDialog +[X] MultiChoiceDialog +[X] PageSetupDialog +[X] PrintDialog +[X] ProgressDialog +[X] SingleChoiceDialog +[X] TextEntryDialog + +More Dialogs Demos +================== +[X] ImageBrowser + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\imagebrowser.py:144: wxPyD + eprecationWarning: Call to deprecated item BitmapFromBuffer. Use :meth:`Bitmap.F + romBuffer` or :meth:`Bitmap.FromBufferAndAlpha` instead. + return wx.BitmapFromBuffer(size, size, data) +[X] ScrolledMessageDialog + +Core Windows/Controls Demos +=========================== +[X] BitmapButton +[X] Button +[X] CheckBox +[X] CheckListBox +[X] Choice +[X] ComboBox +[X] CommandLinkButton +[ ] DVC_CustomRenderer + TODO + TypeError: invalid result type from MyCustomRenderer.Render() +[ ] DVC_DataViewModel +[X] DVC_IndexListModel +[X] DVC_ListCtrl +[X] DVC_TreeCtrl +[X] Gauge +[ ] Grid +[ ] Grid_MegaExample +[ ] GridLabelRenderer +[X] ListBox +[X] ListCtrl +[X] ListCtrl_virtual +[X] ListCtrl_edit + TODO + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\mixins\listctrl.py + ", line 561, in OnLeftDown + self.OpenEditor(col, row) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\mixins\listctrl.py + ", line 572, in OpenEditor + evt.m_item.SetId(item.GetId()) + AttributeError: 'ListEvent' object has no attribute 'm_item' +[X] Menu +[X] PopupMenu +[X] PopupWindow +[X] RadioBox +[X] RadioButton +[X] SashWindow +[X] ScrolledWindow +[X] SearchCtrl +[X] Slider +[X] SpinButton +[X] SpinCtrl +[X] SpinCtrlDouble +[X] SplitterWindow +[X] StaticBitmap +[X] StaticBox +[X] StaticText +[ ] StatusBar +[X] StockButtons +[X] TextCtrl + TODO + Text Positions Ctrl is Giving an + IndexError: string out of range + when clicking at the end of text +[X] ToggleButton +[X] ToolBar +[X] TreeCtrl +[X] Validator + +"Book" Controls Demos +===================== +[ ] AUI_Notebook +[X] Choicebook +[X] FlatNotebook +[X] Listbook +[X] Notebook +[X] Toolbook +[X] Treebook + TODO + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\core.py", line 1948, i + n Notify + self.notify() + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\core.py", line 3017, i + n Notify + self.result = self.callable(*self.args, **self.kwargs) + File "Treebook.py", line 68, in AdjustSize + self.GetTreeCtrl().InvalidateBestSize() + AttributeError: 'TestTB' object has no attribute 'GetTreeCtrl' + +Custom Controls Demos +===================== +[ ] AnalogClock +[X] ColourSelect + TODO + Traceback (most recent call last): + File "ColourSelect.py", line 81, in OnSelectColour + self.log.WriteText("Colour selected: %s" % str(event.GetValue())) + AttributeError: 'CommandEvent' object has no attribute 'GetValue' +[X] ComboTreeBox + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\combotreebox.py:532: wxPyD + eprecationWarning: Call to deprecated item. The TreeItemData class no longer exi + sts, just pass your object directly to the tree instead. + data=wx.TreeItemData(clientData)) +[ ] Editor + TODO + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\editor\editor.py", + line 194, in OnPaint + self.UpdateView(dc) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\editor\editor.py", + line 183, in UpdateView + if dc.Ok(): + AttributeError: 'PaintDC' object has no attribute 'Ok' +[X] GenericButtons +[X] GenericDirCtrl + NOTE + Slow +[X] ItemsPicker +[ ] LEDNumberCtrl +[ ] MultiSash + TODO + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\multisash.py", lin + e 617, in OnPaint + highlight = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT), + 1, wx.SOLID) + AttributeError: 'module' object has no attribute 'SystemSettings_GetColour' + + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\multisash.py:659: wxPyDepr + ecationWarning: Using deprecated class. Use Cursor instead. + self.SetCursor(wx.StockCursor(wx.CURSOR_BULLSEYE)) + + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\multisash.py:655: wxPyDepr + ecationWarning: Using deprecated class. Use Cursor instead. + self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) +[X] PlateButton + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\platebtn.py:135: wxPyDepre + cationWarning: Using deprecated class. Use Control instead. + name=name) + + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\platebtn.py:145: wxPyDepre + cationWarning: Call to deprecated item BitmapFromImage. Use :class:`Bitmap` inst + ead + self._bmp['disable'] = wx.BitmapFromImage(img) +[X] PopupControl + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\popupctl.py:157: wxPyDepre + cationWarning: Using deprecated class. Use Control instead. + wx.PyControl.__init__(self, *_args, **_kwargs) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\popupctl.py:32: wxPyDeprec + ationWarning: Using deprecated class. Use Control instead. + wx.PyControl.__init__(self, *_args, **_kwargs) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\popupctl.py:181: wxPyDepre + cationWarning: Call to deprecated item. Use SetSize instead. + self.textCtrl.SetDimensions(0, 0, w - self.marginWidth - self.buttonWidth, h) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\popupctl.py:182: wxPyDepre + cationWarning: Call to deprecated item. Use SetSize instead. + self.bCtrl.SetDimensions(w - self.buttonWidth, 0, self.buttonWidth, h) +[ ] PyColourChooser +[ ] TreeListCtrl + +AGW Demos +========= +[X] AdvancedSplash +[X] AquaButton +[X] AUI +[X] BalloonTip +[X] ButtonPanel +[X] CubeColourDialog +[ ] CustomTreeCtrl + TODO + wx.WXK_PRIOR +[ ] FlatMenu + TODO + Crashes on opening menu +[X] FlatNotebook +[X] FloatSpin +[X] FoldPanelBar +[X] FourWaySplitter +[X] GenericMessageDialog +[X] GradientButton +[X] HyperLinkCtrl +[ ] HyperTreeList + TODO + wx.WXK_PRIOR +[X] AGWInfoBar +[X] KnobCtrl + TODO + Traceback (most recent call last): + File "agw\KnobCtrl.py", line 166, in OnSecondColour + self.knob1.SetSecondGradientColour(event.GetValue()) + AttributeError: 'CommandEvent' object has no attribute 'GetValue' +[X] LabelBook +[X] MultiDirDialog +[X] PeakMeter +[ ] PersistentControls + TODO + wx.HtmlListBox +[X] PieCtrl + TODO + Traceback (most recent call last): + File "agw\PieCtrl.py", line 44, in Notify + self._parent._progresspie.SetValue(self._parent._progresspie.GetValue() + se + lf._parent._incr) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\agw\piectrl.py", l + ine 924, in SetValue + self.Refresh() + RuntimeError: wrapped C/C++ object of type ProgressPie has been deleted +[X] PyBusyInfo +[X] PyCollapsiblePane +[X] PyGauge +[X] PyProgress + TODO + Crashes if color is changed before starting + Also cancel button doesn't work +[ ] RibbonBar + TODO + Traceback (most recent call last): + File "agw\RibbonBar.py", line 902, in OnButton1 + size=(800, 600), log=self.log) + File "agw\RibbonBar.py", line 357, in __init__ + self._primary_gallery = self.PopulateColoursPanel(primary_panel, self._defau + lt_primary, ID_PRIMARY_COLOUR) + File "agw\RibbonBar.py", line 473, in PopulateColoursPanel + self.AddColourToGallery(gallery, "BLUE", dc) + File "agw\RibbonBar.py", line 803, in AddColourToGallery + item = gallery.Append(bitmap, wx.ID_ANY) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\agw\ribbon\gallery + .py", line 628, in Append + raise Exception("exception") + Exception: exception +[X] RulerCtrl + TODO + Traceback (most recent call last): + File "agw\RulerCtrl.py", line 378, in OnLabelColour + self.ruler3.SetLabelColour(event.GetValue()) + AttributeError: 'CommandEvent' object has no attribute 'GetValue' +[X] ShapedButton +[X] ShortcutEditor +[X] SpeedMeter + TODO + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\agw\speedmeter.py" + , line 380, in OnSize + self.UpdateDrawing() + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\agw\speedmeter.py" + , line 394, in UpdateDrawing + self.Draw(dc) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\agw\speedmeter.py" + , line 900, in Draw + width, height, dummy = fancytext.GetFullExtent(strings, dc) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\fancytext.py", lin + e 348, in GetFullExtent + RenderToRenderer(str, renderer, enclose) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\fancytext.py", lin + e 331, in RenderToRenderer + p.Parse(str, 1) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\fancytext.py", lin + e 123, in startElement + getattr(self, method)(attrs) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\fancytext.py", lin + e 232, in start + self.characterData(code) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\fancytext.py", lin + e 141, in characterData + width, height, descent, extl = self.dc.GetFullTextExtent(chunk) + UnicodeDecodeError: 'utf8' codec can't decode byte 0xf0 in position 0: unexpecte + d end of data +[X] SuperToolTip +[X] ThumbnailCtrl +[X] ToasterBox + TODO + is crashing on/after toasty +[X] UltimateListCtrl + TODO + Windows7ExplorerContents +[ ] XLSGrid +[X] ZoomBar + TODO + Traceback (most recent call last): + File "agw\ZoomBar.py", line 154, in OnZoomColour + colour = event.GetValue() + AttributeError: 'CommandEvent' object has no attribute 'GetValue' + +More Windows/Controls Demos +=========================== +[ ] ActiveX_FlashWindow +[ ] ActiveX_IEHtmlWindow +[ ] ActiveX_PDFWindow +[X] BitmapComboBox +[X] Calendar + TODO + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\calendar.py" + #replaceall wx.PyControl with wx.Control + #replaceall DrawRectangleRect with DrawRectangle + #replaceall DrawRectanglePointSize with DrawRectangle + #replaceall DrawLinePoint with DrawLine + #replaceall DrawTextPoint with DrawText + #replaceall SystemSettings_ with SystemSettings. + + #Commented out dc BeginDrawing() and EndDrawing() stuff + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\calendar.py", line + 985, in OnPaint + self.DoDrawing(DC) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\calendar.py", line + 989, in DoDrawing + DC.BeginDrawing() + AttributeError: 'PaintDC' object has no attribute 'BeginDrawing' + + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\calendar.py", line + 768, in OnLeftEvent + self.ProcessClick(event) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\calendar.py", line + 761, in ProcessClick + key = self.GetDayHit(self.x, self.y) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\calendar.py", line + 949, in GetDayHit + if wx.IntersectRect(ms_rect, val) is not None: + AttributeError: 'module' object has no attribute 'IntersectRect' + +[X] CalendarCtrl + TODO + could use some work/cleanup +[X] CheckListCtrlMixin +[X] CollapsiblePane +[X] ComboCtrl +[ ] ContextHelp +[X] DatePickerCtrl +[ ] DynamicSashWindow +[ ] EditableListBox +[X] ExpandoTextCtrl + TODO + Traceback (most recent call last): + File "ExpandoTextCtrl.py", line 82, in OnSetMaxHeight + dlg = wx.NumberEntryDialog(self, "", "Enter new max height:", + AttributeError: 'module' object has no attribute 'NumberEntryDialog' +[X] FancyText +[X] FileBrowseButton + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\filebrowsebutton.py:132: w + xPyDeprecationWarning: Call to deprecated item. Use SetToolTip instead. + textControl.SetToolTipString( self.toolTip ) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\filebrowsebutton.py:145: w + xPyDeprecationWarning: Call to deprecated item. Use SetToolTip instead. + button.SetToolTipString( self.toolTip ) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\filebrowsebutton.py:109: w + xPyDeprecationWarning: Call to deprecated item. Use SetSize instead. + self.SetDimensions(-1, -1, size.width, size.height, wx.SIZE_USE_EXISTING) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\filebrowsebutton.py:245: w + xPyDeprecationWarning: Call to deprecated item. Use SetToolTip instead. + textControl.SetToolTipString( self.toolTip ) +[X] FloatBar +[X] FloatCanvas +[X] HtmlWindow + TODO + Traceback (most recent call last): + File "HtmlWindow.py", line 177, in OnViewSource + source = self.html.GetParser().GetSource() + AttributeError: 'MyHtmlWindow' object has no attribute 'GetParser' +[X] HTML2_WebView +[X] InfoBar +[ ] IntCtrl + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\intctrl.py:89: wxPyDepreca + tionWarning: Using deprecated class. Use Validator instead. + wx.PyValidator.__init__(self) +[ ] MVCTree + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\mvctree.py:171: wxPyDeprec + ationWarning: Using deprecated class. Use Colour instead. + self.textcolor = wx.NamedColour("BLACK") + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\mvctree.py:172: wxPyDeprec + ationWarning: Using deprecated class. Use Colour instead. + self.bgcolor = wx.NamedColour("WHITE") + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\mvctree.py:173: wxPyDeprec + ationWarning: Using deprecated class. Use Colour instead. + self.fgcolor = wx.NamedColour("BLUE") + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\mvctree.py:174: wxPyDeprec + ationWarning: Using deprecated class. Use Colour instead. + self.linecolor = wx.NamedColour("GREY") + :40: wxPyDeprecationWarning: Call to deprecated item __call__. Use :meth + :`EvtHandler.Bind` instead. + :41: wxPyDeprecationWarning: Call to deprecated item __call__. Use :meth + :`EvtHandler.Bind` instead. + :42: wxPyDeprecationWarning: Call to deprecated item __call__. Use :meth + :`EvtHandler.Bind` instead. + :43: wxPyDeprecationWarning: Call to deprecated item __call__. Use :meth + :`EvtHandler.Bind` instead. + :44: wxPyDeprecationWarning: Call to deprecated item __call__. Use :meth + :`EvtHandler.Bind` instead. + :45: wxPyDeprecationWarning: Call to deprecated item __call__. Use :meth + :`EvtHandler.Bind` instead. + :46: wxPyDeprecationWarning: Call to deprecated item __call__. Use :meth + :`EvtHandler.Bind` instead. + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\mvctree.py", line + 1145, in OnPaint + self.painter.Paint(dc, self.currentRoot, self.doubleBuffered) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\mvctree.py", line + 606, in Paint + dc.BeginDrawing() + AttributeError: 'PaintDC' object has no attribute 'BeginDrawing' +[X] MaskedEditControls + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\combobox.py:266: wx + PyDeprecationWarning: Call to deprecated item. Use SetTextSelection instead. + return self.SetMark( sel_start, sel_to ) +[X] MaskedNumCtrl +[ ] MediaCtrl +[X] MultiSplitterWindow + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\splitter.py:68: wxPyDeprec + ationWarning: Using deprecated class. Use Panel instead. + wx.PyPanel.__init__(self, parent, id, pos, size, style, name) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\splitter.py:83: wxPyDeprec + ationWarning: Using deprecated class. Use Cursor instead. + self._sashCursorWE = wx.StockCursor(wx.CURSOR_SIZEWE) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\splitter.py:84: wxPyDeprec + ationWarning: Using deprecated class. Use Cursor instead. + self._sashCursorNS = wx.StockCursor(wx.CURSOR_SIZENS) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\splitter.py:709: wxPyDepre + cationWarning: Call to deprecated item. Use SetSize instead. + cw - 2*border, ch - 2*border) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\splitter.py:717: wxPyDepre + cationWarning: Call to deprecated item. Use SetSize instead. + self._windows[idx].SetDimensions(x, y, spos, h) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\splitter.py:721: wxPyDepre + cationWarning: Call to deprecated item. Use SetSize instead. + self._windows[idx+1].SetDimensions(x, y, last, h) +[X] OwnerDrawnComboBox +[X] Pickers +[ ] PropertyGrid +[X] PyCrust +[ ] PyPlot + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\plot.py:586: wxPyDeprecati + onWarning: Using deprecated class. Use Cursor instead. + self.HandCursor = wx.CursorFromImage(Hand.GetImage()) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\plot.py:587: wxPyDeprecati + onWarning: Using deprecated class. Use Cursor instead. + self.GrabHandCursor = wx.CursorFromImage(GrabHand.GetImage()) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\plot.py:588: wxPyDeprecati + onWarning: Using deprecated class. Use Cursor instead. + self.MagCursor = wx.CursorFromImage(MagPlus.GetImage()) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\plot.py:1462: wxPyDeprecat + ionWarning: Call to deprecated item EmptyBitmap. Use :class:`Bitmap` instead + self._Buffer = wx.EmptyBitmap(Size.width, Size.height) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\plot.py:659: wxPyDeprecati + onWarning: Using deprecated class. Use Colour instead. + self._gridColour = wx.NamedColour('black') +[X] PyShell +[X] ResizeWidget + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\resizewidget.py:49: wxPyDe + precationWarning: Using deprecated class. Use Panel instead. + wx.PyPanel.__init__(self, *args, **kw) + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\resizewidget.py", + line 176, in OnSize + cr = wx.RectPS((0,0), sz - (RW_THICKNESS, RW_THICKNESS)) + AttributeError: 'module' object has no attribute 'RectPS' +[ ] RichTextCtrl +[X] ScrolledPanel +[ ] SplitTree +[X] StyledTextCtrl_1 +[X] StyledTextCtrl_2 +[ ] TablePrint + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\printout.py:717: wxPyDepre + cationWarning: Using deprecated class. Use Colour instead. + self.row_def_line_colour = wx.NamedColour('BLACK') + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\printout.py:720: wxPyDepre + cationWarning: Using deprecated class. Use Colour instead. + self.column_def_line_colour = wx.NamedColour('BLACK') + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\printout.py:722: wxPyDepre + cationWarning: Using deprecated class. Use Colour instead. + self.column_colour = wx.NamedColour('WHITE') + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\printout.py:724: wxPyDepre + cationWarning: Using deprecated class. Use Colour instead. + self.label_colour = wx.NamedColour('LIGHT GREY') + :72: wxPyDeprecationWarning: Using deprecated class. Use Colour instead. + + :75: wxPyDeprecationWarning: Using deprecated class. Use Colour instead. + + :79: wxPyDeprecationWarning: Using deprecated class. Use Colour instead. + + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\printout.py:917: wxPyDepre + cationWarning: Call to deprecated item. Use IsOk instead. + if not self.preview.Ok(): + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\printout.py", line + 1134, in OnPrintPage + self.canvas.DoDrawing(dc) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\printout.py", line + 945, in DoDrawing + DC.BeginDrawing() + AttributeError: 'DC' object has no attribute 'BeginDrawing' +[X] Throbber + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\throbber.py:68: wxPyDeprec + ationWarning: Using deprecated class. Use Panel instead. + wx.PyPanel.__init__(self, parent, id, pos, size, style, name) +[ ] Ticker + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\ticker.py:45: wxPyDeprecat + ionWarning: Using deprecated class. Use Control instead. + wx.PyControl.__init__(self, parent, id=id, pos=pos, size=size, style=style, na + me=name) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\ticker.py:56: wxPyDeprecat + ionWarning: Call to deprecated item __call__. Use :meth:`EvtHandler.Bind` instea + d. + wx.EVT_TIMER(self, -1, self.OnTick) +[X] TimeCtrl + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py:391: wx + PyDeprecationWarning: Call to deprecated item DateTimeFromDMY. Use :meth:`DateTi + me.FromDMY` instead. + wxdt = wx.DateTimeFromDMY(1, 0, 1970) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py:531: wx + PyDeprecationWarning: Call to deprecated item DateTimeFromDMY. Use :meth:`DateTi + me.FromDMY` instead. + wxdt = wx.DateTimeFromDMY(1, 0, 1970) + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py:769: wx + PyDeprecationWarning: Call to deprecated item DateTimeFromDMY. Use :meth:`DateTi + me.FromDMY` instead. + wxdt = wx.DateTimeFromDMY(1, 0, 1970) + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py + ", line 1177, in __OnTextChange + if not BaseMaskedTextCtrl._OnTextChange(self, event): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 2966, in _OnTextChange + self._CheckValid() # Recolor control as appropriate + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5362, in _CheckValid + valid = self._validateTime(value) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5556, in _validateTime + dateHandler = wx.DateTime_Today() + AttributeError: 'module' object has no attribute 'DateTime_Today' + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py + ", line 1177, in __OnTextChange + if not BaseMaskedTextCtrl._OnTextChange(self, event): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 2966, in _OnTextChange + self._CheckValid() # Recolor control as appropriate + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5362, in _CheckValid + valid = self._validateTime(value) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5556, in _validateTime + dateHandler = wx.DateTime_Today() + AttributeError: 'module' object has no attribute 'DateTime_Today' + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py + ", line 1177, in __OnTextChange + if not BaseMaskedTextCtrl._OnTextChange(self, event): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 2966, in _OnTextChange + self._CheckValid() # Recolor control as appropriate + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5362, in _CheckValid + valid = self._validateTime(value) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5556, in _validateTime + dateHandler = wx.DateTime_Today() + AttributeError: 'module' object has no attribute 'DateTime_Today' + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py + ", line 1177, in __OnTextChange + if not BaseMaskedTextCtrl._OnTextChange(self, event): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 2966, in _OnTextChange + self._CheckValid() # Recolor control as appropriate + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5362, in _CheckValid + valid = self._validateTime(value) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5556, in _validateTime + dateHandler = wx.DateTime_Today() + AttributeError: 'module' object has no attribute 'DateTime_Today' + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py + ", line 1177, in __OnTextChange + if not BaseMaskedTextCtrl._OnTextChange(self, event): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 2966, in _OnTextChange + self._CheckValid() # Recolor control as appropriate + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5362, in _CheckValid + valid = self._validateTime(value) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5556, in _validateTime + dateHandler = wx.DateTime_Today() + AttributeError: 'module' object has no attribute 'DateTime_Today' + Traceback (most recent call last): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\timectrl.py + ", line 1177, in __OnTextChange + if not BaseMaskedTextCtrl._OnTextChange(self, event): + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 2966, in _OnTextChange + self._CheckValid() # Recolor control as appropriate + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5362, in _CheckValid + valid = self._validateTime(value) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\masked\maskededit. + py", line 5556, in _validateTime + dateHandler = wx.DateTime_Today() + AttributeError: 'module' object has no attribute 'DateTime_Today' +[ ] TreeMixin +[ ] VListBox + +Window Layout Demos +=================== +[ ] GridBagSizer +[X] LayoutAnchors +[X] LayoutConstraints +[X] Layoutf +[ ] RowColSizer + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\rcsizer.py:63: wxPyDepreca + tionWarning: Using deprecated class. Use Sizer instead. + wx.PySizer.__init__(self) +[X] ScrolledPanel +[X] SizedControls +[X] Sizers +[X] WrapSizer +[ ] XmlResource +[ ] XmlResourceHandler +[ ] XmlResourceSubclass + +Process and Events Demos +[X] DelayedResult +[X] EventManager + TODO + self._publish(msgKwargs) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\pubsub\core\topico + bj.py", line 340, in _publish + self.__sendMessage(data, self, iterState) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\pubsub\core\topico + bj.py", line 359, in __sendMessage + self._mix_callListener(listener, data, iterState) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\pubsub\core\kwargs + \publishermixin.py", line 64, in _mix_callListener + listener(iterState.filteredArgs, self, msgKwargs) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\pubsub\core\kwargs + \listenerimpl.py", line 27, in __call__ + cb(**kwargs) + File "C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\evtmgr.py", line 4 + 67, in deliverEvent + self.eventHandler(message) + File "EventManager.py", line 184, in makeColor + self.makeColorFromTuple(mouseEvent.GetPositionTuple()) + AttributeError: 'MouseEvent' object has no attribute 'GetPositionTuple' +[X] KeyEvents +[X] Process +[X] PythonEvents +[X] Threads +[X] Timer +[ ] #'infoframe # needs better explanation and some fixing + +Clipboard and DnD Demos +======================= +[X] CustomDragAndDrop + TODO + DoodleDrop isn't showing upon drop +[X] DragAndDrop + TODO + TypeError: Invalid result type upon drops +[X] URLDragAndDrop + +Using Images Demos +================== +[X] AdjustChannels +[X] AlphaDrawing +[X] AnimateCtrl +[X] ArtProvider +[X] BitmapFromBuffer +[X] Cursor +[ ] DragImage +[X] Image +[X] ImageAlpha +[X] ImageFromStream +[X] Img2PyArtProvider +[ ] Mask +[X] RawBitmapAccess +[X] Throbber + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\throbber.py:68: wxPyDeprec + ationWarning: Using deprecated class. Use Panel instead. + wx.PyPanel.__init__(self, parent, id, pos, size, style, name) + +Miscellaneous Demos +=================== +[X] AlphaDrawing +[ ] Cairo +[ ] Cairo_Snippets +[X] ColourDB +[ ] #'DialogUnits # needs more explanations +[X] DragScroller + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\dragscroller.py:49: wxPyDe + precationWarning: Using deprecated class. Use Cursor instead. + self.scrollwin.SetCursor(wx.StockCursor(wx.CURSOR_SIZING)) +[X] DrawXXXList +[X] FileHistory +[X] FontEnumerator +[X] GraphicsContext +[ ] GraphicsGradient +[ ] GLCanvas +[X] I18N + TODO + C:\Python27\lib\site-packages\wx-2.9.5-phoenix\wx\lib\langlistctrl.py:375: wxPyD + eprecationWarning: Call to deprecated item. Use InsertItem instead. + self.InsertImageStringItem(i, self.choices[i], i) +[X] Joystick + TODO + Needs more work and tested with a joystick. I dont have one. +[ ] MimeTypesManager +[X] MouseGestures +[ ] OGL +[ ] PDFViewer +[X] PenAndBrushStyles +[X] PrintFramework +[ ] PseudoDC +[X] RendererNative +[X] ShapedWindow +[X] Sound +[X] StandardPaths +[X] SystemSettings +[X] UIActionSimulator +[X] Unicode \ No newline at end of file diff --git a/demo/Wizard.py b/demo/Wizard.py index eceba135..910d9979 100644 --- a/demo/Wizard.py +++ b/demo/Wizard.py @@ -1,7 +1,9 @@ -import wx -import wx.wizard as wiz -import images +import wx +import wx.adv +from wx.adv import Wizard as wiz +from wx.adv import WizardPage, WizardPageSimple +import images #---------------------------------------------------------------------- @@ -16,17 +18,17 @@ def makePageTitle(wizPg, title): #---------------------------------------------------------------------- -class TitledPage(wiz.WizardPageSimple): +class TitledPage(wx.adv.WizardPageSimple): def __init__(self, parent, title): - wiz.WizardPageSimple.__init__(self, parent) + WizardPageSimple.__init__(self, parent) self.sizer = makePageTitle(self, title) #---------------------------------------------------------------------- -class SkipNextPage(wiz.PyWizardPage): +class SkipNextPage(wx.adv.WizardPage): def __init__(self, parent, title): - wiz.PyWizardPage.__init__(self, parent) + WizardPage.__init__(self, parent) self.next = self.prev = None self.sizer = makePageTitle(self, title) @@ -59,9 +61,9 @@ class SkipNextPage(wiz.PyWizardPage): #---------------------------------------------------------------------- -class UseAltBitmapPage(wiz.PyWizardPage): +class UseAltBitmapPage(WizardPage): def __init__(self, parent, title): - wiz.PyWizardPage.__init__(self, parent) + WizardPage.__init__(self, parent) self.next = self.prev = None self.sizer = makePageTitle(self, title) @@ -103,9 +105,9 @@ class TestPanel(wx.Panel): b = wx.Button(self, -1, "Run Dynamic Wizard", pos=(50, 100)) self.Bind(wx.EVT_BUTTON, self.OnRunDynamicWizard, b) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnWizPageChanged) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChanging) - self.Bind(wiz.EVT_WIZARD_CANCEL, self.OnWizCancel) + self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGED, self.OnWizPageChanged) + self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChanging) + self.Bind(wx.adv.EVT_WIZARD_CANCEL, self.OnWizCancel) def OnWizPageChanged(self, evt): @@ -145,7 +147,7 @@ class TestPanel(wx.Panel): def OnRunSimpleWizard(self, evt): # Create the wizard and the pages - wizard = wiz.Wizard(self, -1, "Simple Wizard", images.WizTest1.GetBitmap()) + wizard = wiz(self, -1, "Simple Wizard", images.WizTest1.GetBitmap()) page1 = TitledPage(wizard, "Page 1") page2 = TitledPage(wizard, "Page 2") page3 = TitledPage(wizard, "Page 3") @@ -161,9 +163,9 @@ wxWizardPageSimple class can easily be used for the pages.""")) page4.sizer.Add(wx.StaticText(page4, -1, "\nThis is the last page.")) # Use the convenience Chain function to connect the pages - wiz.WizardPageSimple.Chain(page1, page2) - wiz.WizardPageSimple.Chain(page2, page3) - wiz.WizardPageSimple.Chain(page3, page4) + WizardPageSimple.Chain(page1, page2) + WizardPageSimple.Chain(page2, page3) + WizardPageSimple.Chain(page3, page4) wizard.GetPageAreaSizer().Add(page1) if wizard.RunWizard(page1): @@ -172,14 +174,13 @@ wxWizardPageSimple class can easily be used for the pages.""")) wx.MessageBox("Wizard was cancelled", "That's all folks!") - def OnRunDynamicWizard(self, evt): # Create the wizard and the pages #wizard = wx.PreWizard() #wizard.SetExtraStyle(wx.WIZARD_EX_HELPBUTTON) #wizard.Create(self, self.ID_wiz, "Simple Wizard", # images.WizTest1.GetBitmap()) - wizard = wiz.Wizard(self, -1, "Dynamic Wizard", images.WizTest1.GetBitmap()) + wizard = wiz(self, -1, "Dynamic Wizard", images.WizTest1.GetBitmap()) page1 = TitledPage(wizard, "Page 1") page2 = SkipNextPage(wizard, "Page 2") diff --git a/demo/XmlResource.py b/demo/XmlResource.py index 5d241b1d..89f653f9 100644 --- a/demo/XmlResource.py +++ b/demo/XmlResource.py @@ -31,8 +31,8 @@ class TestPanel(wx.Panel): elif 1: # or from a Virtual FileSystem: - wx.FileSystem_AddHandler(wx.MemoryFSHandler()) - wx.MemoryFSHandler_AddFile("XRC_Resources/data_file", resourceText) + wx.FileSystem.AddHandler(wx.MemoryFSHandler()) + wx.MemoryFSHandler().AddFile("XRC_Resources/data_file", resourceText) res = xrc.XmlResource("memory:XRC_Resources/data_file") else: diff --git a/demo/agw/AUI.py b/demo/agw/AUI.py index 2c9f45de..6bb9a4d7 100644 --- a/demo/agw/AUI.py +++ b/demo/agw/AUI.py @@ -362,12 +362,12 @@ ID_NotebookMultiLine = ID_PaneBorderSize + 18 # -- SizeReportCtrl -- # (a utility control that always reports it's client size) -class SizeReportCtrl(wx.PyControl): +class SizeReportCtrl(wx.Control): def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, mgr=None): - wx.PyControl.__init__(self, parent, id, pos, size, style=wx.NO_BORDER) + wx.Control.__init__(self, parent, id, pos, size, style=wx.NO_BORDER) self._mgr = mgr self.Bind(wx.EVT_PAINT, self.OnPaint) @@ -557,7 +557,7 @@ class SettingsPanel(wx.Panel): s15.Add((1, 1), 1, wx.EXPAND) s15.SetItemMinSize(1, (180, 20)) - grid_sizer = wx.GridSizer(0, 2) + grid_sizer = wx.GridSizer(rows=0, cols=2, vgap=5, hgap=5) grid_sizer.SetHGap(5) grid_sizer.Add(s1) grid_sizer.Add(s4) @@ -607,14 +607,14 @@ class SettingsPanel(wx.Panel): def CreateColourBitmap(self, c): - image = wx.EmptyImage(25, 14) + image = wx.Image(25, 14) for x in xrange(25): for y in xrange(14): pixcol = c if x == 0 or x == 24 or y == 0 or y == 13: pixcol = wx.BLACK - image.SetRGB(x, y, pixcol.Red(), pixcol.Green(), pixcol.Blue()) + image.SetRGB(wx.Rect(wx.Size(25, 14)), pixcol.Red(), pixcol.Green(), pixcol.Blue()) return image.ConvertToBitmap() @@ -726,13 +726,13 @@ class SettingsPanel(wx.Panel): # Class ProgressGauge # ---------------------------------------------------------------------------- # -class ProgressGauge(wx.PyWindow): +class ProgressGauge(wx.Window): """ This class provides a visual alternative for wx.Gauge.""" def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=(-1,30)): """ Default class constructor. """ - wx.PyWindow.__init__(self, parent, id, pos, size, style=wx.BORDER_NONE) + wx.Window.__init__(self, parent, id, pos, size, style=wx.BORDER_NONE) self._value = 0 self._steps = 16 @@ -786,8 +786,8 @@ class ProgressGauge(wx.PyWindow): self.DrawProgress(dc, xsize, ysize, increment) dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.SetPen(wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRADIENTINACTIVECAPTION))) - dc.DrawRectangleRect(self.GetClientRect()) + dc.SetPen(wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRADIENTINACTIVECAPTION))) + dc.DrawRectangle(self.GetClientRect()) def LightColour(self, colour, percent): @@ -1050,10 +1050,10 @@ class AuiFrame(wx.Frame): guides_menu.AppendRadioItem(ID_AeroGuides, "Aero-Style Docking Guides") guides_menu.AppendRadioItem(ID_WhidbeyGuides, "Whidbey-Style Docking Guides") - perspectives_menu.AppendMenu(wx.ID_ANY, "Frame Perspectives", self._perspectives_menu) - perspectives_menu.AppendMenu(wx.ID_ANY, "AuiNotebook Perspectives", self._nb_perspectives_menu) + perspectives_menu.Append(wx.ID_ANY, "Frame Perspectives", self._perspectives_menu) + perspectives_menu.Append(wx.ID_ANY, "AuiNotebook Perspectives", self._nb_perspectives_menu) perspectives_menu.AppendSeparator() - perspectives_menu.AppendMenu(wx.ID_ANY, "Docking Guides", guides_menu) + perspectives_menu.Append(wx.ID_ANY, "Docking Guides", guides_menu) action_menu = wx.Menu() action_menu.AppendCheckItem(ID_VetoTree, "Veto Floating Of Tree Pane") @@ -1072,7 +1072,7 @@ class AuiFrame(wx.Frame): self._requestPanes[ids] = pane.name attention_menu.Append(ids, pane.caption) - action_menu.AppendMenu(wx.ID_ANY, "Request User Attention For", attention_menu) + action_menu.Append(wx.ID_ANY, "Request User Attention For", attention_menu) help_menu = wx.Menu() help_menu.Append(wx.ID_ABOUT, "About...") @@ -1539,7 +1539,7 @@ class AuiFrame(wx.Frame): try: self.gauge.Pulse() - except wx.PyDeadObjectError: + except: self.timer.Stop() @@ -2195,9 +2195,6 @@ class AuiFrame(wx.Frame): auibook = self._mgr.GetPane("notebook_content").window auibook.LoadPerspective(self._nb_perspectives[event.GetId() - ID_FirstNBPerspective]) - self.gauge = ProgressGauge(auibook, size=(55, 15)) - auibook.AddControlToPage(4, self.gauge) - def OnGuides(self, event): @@ -2342,19 +2339,19 @@ class AuiFrame(wx.Frame): m1 = wx.MenuItem(menuPopup, 10001, "Drop Down Item 1") m1.SetBitmap(bmp) - menuPopup.AppendItem(m1) + menuPopup.Append(m1) m2 = wx.MenuItem(menuPopup, 10002, "Drop Down Item 2") m2.SetBitmap(bmp) - menuPopup.AppendItem(m2) + menuPopup.Append(m2) m3 = wx.MenuItem(menuPopup, 10003, "Drop Down Item 3") m3.SetBitmap(bmp) - menuPopup.AppendItem(m3) + menuPopup.Append(m3) m4 = wx.MenuItem(menuPopup, 10004, "Drop Down Item 4") m4.SetBitmap(bmp) - menuPopup.AppendItem(m4) + menuPopup.Append(m4) # line up our menu with the button rect = tb.GetToolRect(event.GetId()) @@ -2521,7 +2518,8 @@ class AuiFrame(wx.Frame): wx.OK | wx.ICON_INFORMATION) if wx.Platform != '__WXMAC__': - dlg.SetFont(wx.Font(8, wx.NORMAL, wx.NORMAL, wx.NORMAL, False)) + dlg.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, + False, '', wx.FONTENCODING_DEFAULT)) dlg.ShowModal() dlg.Destroy() @@ -2611,7 +2609,7 @@ class AuiFrame(wx.Frame): ctrl.AddPage(self.CreateHTMLCtrl(ctrl), "Welcome to AUI", False, page_bmp) panel = wx.Panel(ctrl, -1) - flex = wx.FlexGridSizer(0, 2) + flex = wx.FlexGridSizer(rows=0, cols=2, vgap=2, hgap=2) flex.Add((5, 5)) flex.Add((5, 5)) flex.Add(wx.StaticText(panel, -1, "wxTextCtrl:"), 0, wx.ALL|wx.ALIGN_CENTRE, 5) diff --git a/demo/agw/AquaButton.py b/demo/agw/AquaButton.py index a5e7cc69..1d42dd70 100644 --- a/demo/agw/AquaButton.py +++ b/demo/agw/AquaButton.py @@ -19,7 +19,7 @@ try: except ImportError: # if it's not there locally, try the wxPython lib. import wx.lib.agw.aquabutton as AB - + class AquaButtonDemo(wx.Panel): def __init__(self, parent, log): @@ -29,37 +29,37 @@ class AquaButtonDemo(wx.Panel): self.mainPanel = wx.Panel(self) self.mainPanel.SetBackgroundColour(wx.WHITE) - + # Initialize AquaButton 1 (with image) bitmap = wx.Bitmap( - os.path.normpath(os.path.join(bitmapDir, "aquabutton.png")), + os.path.normpath(os.path.join(bitmapDir, "aquabutton.png")), wx.BITMAP_TYPE_PNG) self.btn1 = AB.AquaButton(self.mainPanel, -1, bitmap, "AquaButton") # Initialize AquaButton 2 (no image) self.btn2 = AB.AquaButton(self.mainPanel, -1, None, "Hello World!") - self.backColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetBackgroundColour()) - self.hoverColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetHoverColour()) - self.textColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetForegroundColour()) + self.backColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetBackgroundColour()) + self.hoverColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetHoverColour()) + self.textColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetForegroundColour()) self.pulseCheck = wx.CheckBox(self.mainPanel, -1, "Pulse On Focus") self.DoLayout() self.BindEvents() - + def DoLayout(self): frameSizer = wx.BoxSizer(wx.VERTICAL) - mainSizer = wx.BoxSizer(wx.VERTICAL) + mainSizer = wx.BoxSizer(wx.VERTICAL) btnSizer = wx.FlexGridSizer(2, 2, 15, 15) colourSizer = wx.FlexGridSizer(2, 3, 1, 10) btnSizer.Add(self.btn1, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL) btnSizer.Add(self.pulseCheck, 0, wx.ALIGN_CENTER_VERTICAL) - + btnSizer.Add(self.btn2, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL) - + labelBack = wx.StaticText(self.mainPanel, -1, "Background Colour") labelHover = wx.StaticText(self.mainPanel, -1, "Hover Colour") labelText = wx.StaticText(self.mainPanel, -1, "Text Colour") @@ -74,17 +74,17 @@ class AquaButtonDemo(wx.Panel): btnSizer.Add(colourSizer, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL) label1 = wx.StaticText(self.mainPanel, -1, "Welcome to the AquaButton demo for wxPython!") - + mainSizer.Add(label1, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 10) mainSizer.Add(btnSizer, 1, wx.EXPAND|wx.ALL, 30) - boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + boldFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) boldFont.SetWeight(wx.BOLD) - + for child in self.mainPanel.GetChildren(): if isinstance(child, wx.StaticText): child.SetFont(boldFont) - + self.mainPanel.SetSizer(mainSizer) mainSizer.Layout() frameSizer.Add(self.mainPanel, 1, wx.EXPAND) @@ -116,13 +116,13 @@ class AquaButtonDemo(wx.Panel): else: self.btn2.SetForegroundColour(colour) - + def OnButton(self, event): obj = event.GetEventObject() self.log.write("You clicked %s\n"%obj.GetLabel()) - + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/agw/BalloonTip.py b/demo/agw/BalloonTip.py index c61d500b..3c03e793 100644 --- a/demo/agw/BalloonTip.py +++ b/demo/agw/BalloonTip.py @@ -9,6 +9,7 @@ import wx from wx.lib.stattext import GenStaticText as StaticText from wx.lib.buttons import GenBitmapButton as BitmapButton +from wx.adv import TaskBarIcon as TaskBarIcon import os import sys @@ -35,7 +36,7 @@ ArtIDs = [ "wx.ART_HELP_PAGE", "wx.ART_QUESTION", "wx.ART_WARNING", "wx.ART_INFORMATION", - "wx.ART_HELP", + "wx.ART_HELP", ] @@ -49,18 +50,18 @@ class BalloonTipDemo(wx.Frame): wx.Frame.__init__(self, parent, title="BalloonTip wxPython Demo ;-)") - self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-2, -1]) # statusbar fields statusbar_fields = [("Welcome To WxPython " + wx.VERSION_STRING), ("BalloonTip Demo")] - + for i in range(len(statusbar_fields)): self.statusbar.SetStatusText(statusbar_fields[i], i) self.SetIcon(images.Mondrian.GetIcon()) self.SetMenuBar(self.CreateMenuBar()) - + panel = wx.Panel(self, -1) mainsizer = wx.FlexGridSizer(3, 4, hgap=2, vgap=2) @@ -81,40 +82,40 @@ class BalloonTipDemo(wx.Frame): # Add A ListBox listbox = wx.ListBox(panel, -1, choices=samplelist, style=wx.LB_SINGLE) # Add A TreeCtrl - isz = (16,16) + isz = (16,16) treecontrol = wx.TreeCtrl(panel, -1) il = wx.ImageList(isz[0], isz[1]) - fldridx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz)) - fldropenidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz)) - fileidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_REPORT_VIEW, wx.ART_OTHER, isz)) + fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz)) + fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz)) + fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_REPORT_VIEW, wx.ART_OTHER, isz)) treecontrol.SetImageList(il) self.il = il root = treecontrol.AddRoot("ROOT") - treecontrol.SetPyData(root, None) + treecontrol.SetItemData(root, None) treecontrol.SetItemImage(root, fldridx, wx.TreeItemIcon_Normal) treecontrol.SetItemImage(root, fldropenidx, wx.TreeItemIcon_Expanded) for ii in range(11): child = treecontrol.AppendItem(root, samplelist[ii]) - treecontrol.SetPyData(child, None) + treecontrol.SetItemData(child, None) treecontrol.SetItemImage(child, fldridx, wx.TreeItemIcon_Normal) treecontrol.SetItemImage(child, fldropenidx, wx.TreeItemIcon_Selected) - # Add A Slider - slider = wx.Slider(panel, -1, 25, 1, 100, + # Add A Slider + slider = wx.Slider(panel, -1, 25, 1, 100, style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS)# | wx.SL_LABELS) - slider.SetTickFreq(5, 1) + slider.SetTickFreq(5) # Add Another TextCtrl textctrl2 = wx.TextCtrl(panel, -1, "Another TextCtrl") # Add A GenStaticText statictext = StaticText(panel, -1, "Hello World!") statictext.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False)) - bmp = wx.ArtProvider_GetBitmap(wx.ART_INFORMATION, + bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_TOOLBAR, (16,16)) # Add A GenBitmapButton bitmapbutton = BitmapButton(panel, -1, bmp) button2 = wx.Button(panel, -1, "Disable BalloonTip") - tbicon = wx.TaskBarIcon() + tbicon = TaskBarIcon() tbicon.SetIcon(images.Mondrian.GetIcon()) controls = list(panel.GetChildren()) @@ -134,7 +135,7 @@ class BalloonTipDemo(wx.Frame): mainsizer.Add(statictext, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, 10) mainsizer.Add(bitmapbutton, 0, wx.ALL, 10) mainsizer.Add(button2, 0, wx.ALL, 10) - + panel.SetSizer(mainsizer) mainsizer.Layout() @@ -145,13 +146,13 @@ class BalloonTipDemo(wx.Frame): # Declare The BalloonTip Top-Left Icons icons = [] for ii in xrange(4): - bmp = wx.ArtProvider_GetBitmap(eval(ArtIDs[ii]), wx.ART_TOOLBAR, (16,16)) + bmp = wx.ArtProvider.GetBitmap(eval(ArtIDs[ii]), wx.ART_TOOLBAR, (16,16)) icons.append(bmp) - + icons.extend([None]*5) for ii in xrange(4, 9): - bmp = wx.ArtProvider_GetBitmap(eval(ArtIDs[ii]), wx.ART_TOOLBAR, (16,16)) + bmp = wx.ArtProvider.GetBitmap(eval(ArtIDs[ii]), wx.ART_TOOLBAR, (16,16)) icons.append(bmp) # Declare The BalloonTip Top Titles @@ -164,12 +165,12 @@ class BalloonTipDemo(wx.Frame): fontthree = wx.Font(9, wx.SWISS, wx.ITALIC, wx.NORMAL, False) fontfour = wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD, True) - # Declare The BalloonTip Top Titles Fonts + # Declare The BalloonTip Top Titles Fonts titlefonts = [None, None, fontone, None, fonttwo, fontthree, None, None, None, fontfour, fontthree, None, None] # Declare The BalloonTip Top Titles Colours - titlecolours = [None, None, wx.WHITE, wx.NamedColour("YELLOW"), None, wx.WHITE, + titlecolours = [None, None, wx.WHITE, wx.YELLOW, None, wx.WHITE, wx.BLUE, wx.RED, None, None, wx.LIGHT_GREY, None, None] # Declare The BalloonTip Messages @@ -250,11 +251,11 @@ class BalloonTipDemo(wx.Frame): # Store The Last BalloonTip Reference To Enable/Disable Globall The # BalloonTip. You Can Store Any Of Them, Not Necessarily The Last One. - self.lasttip = tipballoon + self.lasttip = tipballoon self.gauge = gauge self.count = 0 - - button2.Bind(wx.EVT_BUTTON, self.OnActivateBalloon) + + button2.Bind(wx.EVT_BUTTON, self.OnActivateBalloon) self.Bind(wx.EVT_IDLE, self.IdleHandler) frameSizer = wx.BoxSizer(wx.VERTICAL) @@ -263,28 +264,28 @@ class BalloonTipDemo(wx.Frame): frameSizer.Layout() self.Fit() - self.CenterOnParent() + self.CenterOnParent() def IdleHandler(self, event): - + self.count = self.count + 1 if self.count >= 50: self.count = 0 self.gauge.SetValue(self.count) - + def CreateMenuBar(self): # Make a menubar file_menu = wx.Menu() help_menu = wx.Menu() - + TEST_QUIT = wx.NewId() TEST_ABOUT = wx.NewId() - + file_menu.Append(TEST_QUIT, "&Exit") help_menu.Append(TEST_ABOUT, "&About") @@ -315,30 +316,30 @@ class BalloonTipDemo(wx.Frame): "to me at the following adresses:\n\n" + \ "andrea.gavana@agip.it\n" + "andrea_gavana@tin.it\n\n" + \ "Welcome To wxPython " + wx.VERSION_STRING + "!!" - + dlg = wx.MessageDialog(self, msg, "BalloonTip Demo", wx.OK | wx.ICON_INFORMATION) dlg.SetFont(wx.Font(8, wx.NORMAL, wx.NORMAL, wx.NORMAL, False, "Verdana")) dlg.ShowModal() dlg.Destroy() - + def OnActivateBalloon(self, event): button = event.GetEventObject() label = button.GetLabel() tips = self.lasttip - + if label == "Disable BalloonTip": button.SetLabel("Enable BalloonTip") tips.EnableTip(False) else: button.SetLabel("Disable BalloonTip") tips.EnableTip(True) - + event.Skip() - + #--------------------------------------------------------------------------- diff --git a/demo/agw/ButtonPanel.py b/demo/agw/ButtonPanel.py index 7e51a733..12f1abe5 100644 --- a/demo/agw/ButtonPanel.py +++ b/demo/agw/ButtonPanel.py @@ -44,7 +44,7 @@ class SettingsPanel(wx.MiniFrame): self.targetTitleBar = parent.titleBar self.parent = parent self.panel = wx.Panel(self, -1) - + self.coloursizer_staticbox = wx.StaticBox(self.panel, -1, "Colour Options") self.bottomsizer_staticbox = wx.StaticBox(self.panel, -1, "Size Options") self.stylesizer_staticbox = wx.StaticBox(self.panel, -1, "ButtonPanel Styles") @@ -54,7 +54,7 @@ class SettingsPanel(wx.MiniFrame): self.horizontalgradient = wx.RadioButton(self.panel, -1, "Horizontal Gradient") b = self.CreateColourBitmap(wx.BLACK) - + self.bakbrush = wx.BitmapButton(self.panel, ID_BackgroundColour, b, size=wx.Size(50,25)) self.gradientfrom = wx.BitmapButton(self.panel, ID_GradientFrom, b, size=wx.Size(50,25)) self.gradientto = wx.BitmapButton(self.panel, ID_GradientTo, b, size=wx.Size(50,25)) @@ -90,13 +90,13 @@ class SettingsPanel(wx.MiniFrame): self.Bind(wx.EVT_BUTTON, self.OnSetColour, id=ID_SelectionBrush) self.Bind(wx.EVT_BUTTON, self.OnSetColour, id=ID_SelectionPen) self.Bind(wx.EVT_BUTTON, self.OnSetColour, id=ID_SeparatorColour) - + self.Bind(wx.EVT_SPINCTRL, self.OnSeparator, self.separatorspin) self.Bind(wx.EVT_SPINCTRL, self.OnMargins, self.marginspin) self.Bind(wx.EVT_SPINCTRL, self.OnPadding, self.paddingspin) self.Bind(wx.EVT_SPINCTRL, self.OnBorder, self.borderspin) - self.Bind(wx.EVT_CLOSE, self.OnClose) + self.Bind(wx.EVT_CLOSE, self.OnClose) def __set_properties(self): @@ -118,8 +118,8 @@ class SettingsPanel(wx.MiniFrame): self.marginspin.SetValue(self.targetTitleBar.GetBPArt().GetMetric(bp.BP_MARGINS_SIZE).x) self.paddingspin.SetValue(self.targetTitleBar.GetBPArt().GetMetric(bp.BP_PADDING_SIZE).x) - self.UpdateColours() - + self.UpdateColours() + def __do_layout(self): @@ -145,7 +145,7 @@ class SettingsPanel(wx.MiniFrame): stylesizer = wx.StaticBoxSizer(self.stylesizer_staticbox, wx.VERTICAL) tophsizer = wx.BoxSizer(wx.HORIZONTAL) tophsizer2 = wx.BoxSizer(wx.VERTICAL) - + stylesizer.Add(self.defaultstyle, 0, wx.ALL|wx.EXPAND|wx.ADJUST_MINSIZE, 5) tophsizer.Add(self.gradientstyle, 0, wx.LEFT|wx.RIGHT|wx.EXPAND| @@ -153,7 +153,7 @@ class SettingsPanel(wx.MiniFrame): tophsizer2.Add(self.verticalgradient, 0, wx.BOTTOM|wx.ADJUST_MINSIZE, 3) tophsizer2.Add(self.horizontalgradient, 0, wx.ADJUST_MINSIZE, 0) - + tophsizer.Add(tophsizer2, 1, wx.LEFT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 10) stylesizer.Add(tophsizer, 1, wx.EXPAND, 0) @@ -197,7 +197,7 @@ class SettingsPanel(wx.MiniFrame): coloursizer.Add(leftsizer, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) coloursizer.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0) - + label_6 = wx.StaticText(self.panel, -1, "Text Button Colour:") sizer_6.Add(label_6, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 5) sizer_6.Add((0, 0), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0) @@ -268,25 +268,25 @@ class SettingsPanel(wx.MiniFrame): def CreateColourBitmap(self, c): - - image = wx.EmptyImage(25, 14) - + + image = wx.Image(25, 14) + for x in xrange(25): for y in xrange(14): pixcol = c if x == 0 or x == 24 or y == 0 or y == 13: pixcol = wx.BLACK - - image.SetRGB(x, y, pixcol.Red(), pixcol.Green(), pixcol.Blue()) - + + image.SetRGB(wx.Rect(0, 0, 25, 14), pixcol.Red(), pixcol.Green(), pixcol.Blue()) + return image.ConvertToBitmap() def UpdateColours(self): - + bk = self.targetTitleBar.GetBPArt().GetColour(bp.BP_BACKGROUND_COLOUR) self.bakbrush.SetBitmapLabel(self.CreateColourBitmap(bk)) - + capfrom = self.targetTitleBar.GetBPArt().GetColour(bp.BP_GRADIENT_COLOUR_FROM) self.gradientfrom.SetBitmapLabel(self.CreateColourBitmap(capfrom)) @@ -298,7 +298,7 @@ class SettingsPanel(wx.MiniFrame): bor = self.targetTitleBar.GetBPArt().GetColour(bp.BP_BORDER_COLOUR) self.bordercolour.SetBitmapLabel(self.CreateColourBitmap(bor)) - + btntext = self.targetTitleBar.GetBPArt().GetColour(bp.BP_BUTTONTEXT_COLOUR) self.textbuttoncolour.SetBitmapLabel(self.CreateColourBitmap(btntext)) @@ -307,7 +307,7 @@ class SettingsPanel(wx.MiniFrame): selp = self.targetTitleBar.GetBPArt().GetColour(bp.BP_SELECTION_PEN_COLOUR) self.selectionpen.SetBitmapLabel(self.CreateColourBitmap(selp)) - + sepc = self.targetTitleBar.GetBPArt().GetColour(bp.BP_SEPARATOR_COLOUR) self.separatorcolour.SetBitmapLabel(self.CreateColourBitmap(sepc)) @@ -321,15 +321,15 @@ class SettingsPanel(wx.MiniFrame): self.targetTitleBar.Refresh() event.Skip() - - def OnGradientStyle(self, event): + + def OnGradientStyle(self, event): self.verticalgradient.Enable(True) self.horizontalgradient.Enable(True) self.targetTitleBar.SetStyle(bp.BP_USE_GRADIENT) self.targetTitleBar.Refresh() - + event.Skip() @@ -338,28 +338,28 @@ class SettingsPanel(wx.MiniFrame): self.targetTitleBar.GetBPArt().SetGradientType(bp.BP_GRADIENT_VERTICAL) self.targetTitleBar.SetStyle(bp.BP_USE_GRADIENT) self.targetTitleBar.Refresh() - + event.Skip() - + def OnHorizontalGradient(self, event): self.targetTitleBar.GetBPArt().SetGradientType(bp.BP_GRADIENT_HORIZONTAL) self.targetTitleBar.SetStyle(bp.BP_USE_GRADIENT) self.targetTitleBar.Refresh() - + event.Skip() - + def OnSetColour(self, event): dlg = wx.ColourDialog(self.parent) - + dlg.SetTitle("Colour Picker") - + if dlg.ShowModal() != wx.ID_OK: return - + var = 0 if event.GetId() == ID_BackgroundColour: var = bp.BP_BACKGROUND_COLOUR @@ -380,8 +380,8 @@ class SettingsPanel(wx.MiniFrame): elif event.GetId() == ID_SeparatorColour: var = bp.BP_SEPARATOR_COLOUR else: - return - + return + self.targetTitleBar.GetBPArt().SetColour(var, dlg.GetColourData().GetColour()) self.targetTitleBar.Refresh() self.UpdateColours() @@ -410,7 +410,7 @@ class SettingsPanel(wx.MiniFrame): self.parent.mainPanel.Layout() self.parent.useredited = True - + event.Skip() @@ -422,7 +422,7 @@ class SettingsPanel(wx.MiniFrame): self.targetTitleBar.DoLayout() self.parent.mainPanel.Layout() self.parent.useredited = True - + event.Skip() @@ -435,7 +435,7 @@ class SettingsPanel(wx.MiniFrame): self.parent.mainPanel.Layout() self.parent.useredited = True - + event.Skip() @@ -451,7 +451,7 @@ class ButtonPanelDemo(wx.Frame): def __init__(self, parent, id=wx.ID_ANY, title="ButtonPanel wxPython Demo ;-)", pos=wx.DefaultPosition, size=(640, 400), style=wx.DEFAULT_FRAME_STYLE): - + wx.Frame.__init__(self, parent, id, title, pos, size, style) self.useredited = False @@ -460,7 +460,7 @@ class ButtonPanelDemo(wx.Frame): self.SetIcon(images.Mondrian.GetIcon()) self.CreateMenuBar() - self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-2, -1]) # statusbar fields statusbar_fields = [("ButtonPanel wxPython Demo, Andrea Gavana @ 02 Oct 2006"), @@ -468,18 +468,18 @@ class ButtonPanelDemo(wx.Frame): for i in range(len(statusbar_fields)): self.statusbar.SetStatusText(statusbar_fields[i], i) - + self.mainPanel = wx.Panel(self, -1) self.logtext = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_MULTILINE|wx.TE_READONLY) - - vSizer = wx.BoxSizer(wx.VERTICAL) - self.mainPanel.SetSizer(vSizer) + + vSizer = wx.BoxSizer(wx.VERTICAL) + self.mainPanel.SetSizer(vSizer) self.alignments = [bp.BP_ALIGN_LEFT, bp.BP_ALIGN_RIGHT, bp.BP_ALIGN_TOP, bp.BP_ALIGN_BOTTOM] - + self.alignment = bp.BP_ALIGN_LEFT self.agwStyle = bp.BP_USE_GRADIENT - + self.titleBar = bp.ButtonPanel(self.mainPanel, -1, "A Simple Test & Demo", agwStyle=self.agwStyle, alignment=self.alignment) @@ -491,87 +491,87 @@ class ButtonPanelDemo(wx.Frame): ] self.CreateButtons() self.SetProperties() - - + + def CreateMenuBar(self): mb = wx.MenuBar() - + file_menu = wx.Menu() - + item = wx.MenuItem(file_menu, wx.ID_ANY, "&Quit") - file_menu.AppendItem(item) + file_menu.Append(item) self.Bind(wx.EVT_MENU, self.OnClose, item) edit_menu = wx.Menu() item = wx.MenuItem(edit_menu, wx.ID_ANY, "Set Bar Text") - edit_menu.AppendItem(item) + edit_menu.Append(item) self.Bind(wx.EVT_MENU, self.OnSetBarText, item) - edit_menu.AppendSeparator() + edit_menu.AppendSeparator() submenu = wx.Menu() - + item = wx.MenuItem(submenu, wx.ID_ANY, "BP_ALIGN_LEFT", kind=wx.ITEM_RADIO) - submenu.AppendItem(item) + submenu.Append(item) item.Check(True) self.Bind(wx.EVT_MENU, self.OnAlignment, item) - + item = wx.MenuItem(submenu, wx.ID_ANY, "BP_ALIGN_RIGHT", kind=wx.ITEM_RADIO) - submenu.AppendItem(item) - self.Bind(wx.EVT_MENU, self.OnAlignment, item) - - item = wx.MenuItem(submenu, wx.ID_ANY, "BP_ALIGN_TOP", kind=wx.ITEM_RADIO) - submenu.AppendItem(item) - self.Bind(wx.EVT_MENU, self.OnAlignment, item) - - item = wx.MenuItem(submenu, wx.ID_ANY, "BP_ALIGN_BOTTOM", kind=wx.ITEM_RADIO) - submenu.AppendItem(item) + submenu.Append(item) self.Bind(wx.EVT_MENU, self.OnAlignment, item) - edit_menu.AppendMenu(wx.ID_ANY, "&Alignment", submenu) - + item = wx.MenuItem(submenu, wx.ID_ANY, "BP_ALIGN_TOP", kind=wx.ITEM_RADIO) + submenu.Append(item) + self.Bind(wx.EVT_MENU, self.OnAlignment, item) + + item = wx.MenuItem(submenu, wx.ID_ANY, "BP_ALIGN_BOTTOM", kind=wx.ITEM_RADIO) + submenu.Append(item) + self.Bind(wx.EVT_MENU, self.OnAlignment, item) + + edit_menu.Append(wx.ID_ANY, "&Alignment", submenu) + submenu = wx.Menu() item = wx.MenuItem(submenu, wx.ID_ANY, "Default Style", kind=wx.ITEM_RADIO) - submenu.AppendItem(item) + submenu.Append(item) self.Bind(wx.EVT_MENU, self.OnDefaultStyle, item) - + item = wx.MenuItem(submenu, wx.ID_ANY, "Gradient Style", kind=wx.ITEM_RADIO) - submenu.AppendItem(item) + submenu.Append(item) item.Check(True) self.Bind(wx.EVT_MENU, self.OnGradientStyle, item) - - edit_menu.AppendMenu(wx.ID_ANY, "&Styles", submenu) + + edit_menu.Append(wx.ID_ANY, "&Styles", submenu) edit_menu.AppendSeparator() - + item = wx.MenuItem(submenu, wx.ID_ANY, "Settings Panel") - edit_menu.AppendItem(item) + edit_menu.Append(item) self.Bind(wx.EVT_MENU, self.OnSettingsPanel, item) demo_menu = wx.Menu() - + item = wx.MenuItem(demo_menu, wx.ID_ANY, "Default Demo", kind=wx.ITEM_RADIO) - demo_menu.AppendItem(item) + demo_menu.Append(item) self.Bind(wx.EVT_MENU, self.OnDefaultDemo, item) item = wx.MenuItem(demo_menu, wx.ID_ANY, "Button Only Demo", kind=wx.ITEM_RADIO) - demo_menu.AppendItem(item) + demo_menu.Append(item) self.Bind(wx.EVT_MENU, self.OnButtonOnly, item) - + help_menu = wx.Menu() item = wx.MenuItem(help_menu, wx.ID_ANY, "&About...") - help_menu.AppendItem(item) + help_menu.Append(item) self.Bind(wx.EVT_MENU, self.OnAbout, item) - + mb.Append(file_menu, "&File") mb.Append(edit_menu, "&Edit") mb.Append(demo_menu, "&Demo") mb.Append(help_menu, "&Help") - + self.SetMenuBar(mb) @@ -588,30 +588,30 @@ class ButtonPanelDemo(wx.Frame): self.titleBar = bp.ButtonPanel(self.mainPanel, -1, "A Simple Test & Demo", agwStyle=self.agwStyle, alignment=self.alignment) self.SetProperties() - + self.indices = [] - + for count, png in enumerate(self.pngs): shortHelp = "Button %d"%(count+1) - + if count < 2: # First 2 buttons are togglebuttons kind = wx.ITEM_CHECK longHelp = "ButtonPanel Toggle Button No %d"%(count+1) else: kind = wx.ITEM_NORMAL - longHelp = "Simple Button without label No %d"%(count+1) + longHelp = "Simple Button without label No %d"%(count+1) btn = bp.ButtonInfo(self.titleBar, wx.NewId(), png[0], kind=kind, shortHelp=shortHelp, longHelp=longHelp) - + self.titleBar.AddButton(btn) self.Bind(wx.EVT_BUTTON, self.OnButton, id=btn.GetId()) - + self.indices.append(btn.GetId()) - + if count < 2: # First 2 buttons have also a text btn.SetText(png[1]) @@ -619,30 +619,30 @@ class ButtonPanelDemo(wx.Frame): if count == 2: # Append a separator after the second button self.titleBar.AddSeparator() - + if count == 1: # Add a wx.TextCtrl to ButtonPanel self.titleBar.AddControl(wx.TextCtrl(self.titleBar, -1, "Hello wxPython!")) btn.SetTextAlignment(bp.BP_BUTTONTEXT_ALIGN_RIGHT) - # Add a wx.Choice to ButtonPanel + # Add a wx.Choice to ButtonPanel self.titleBar.AddControl(wx.Choice(self.titleBar, -1, choices=["Hello", "From", "wxPython!"])) - + self.strings = ["First", "Second", "Third", "Fourth"] - self.ChangeLayout() + self.ChangeLayout() self.Thaw() self.titleBar.DoLayout() self.created = True - + def ButtonOnly(self): - + # Here we (re)create the buttons for the button-only demo self.Freeze() - + if self.created: sizer = self.mainPanel.GetSizer() sizer.Detach(0) @@ -654,15 +654,15 @@ class ButtonPanelDemo(wx.Frame): # Buttons are created completely random, with random images, toggle behavior # and text - + self.indices = [] - + for count in xrange(8): itemImage = random.randint(0, 3) hasText = random.randint(0, 1) itemKind = random.randint(0, 1) - + btn = bp.ButtonInfo(self.titleBar, wx.NewId(), self.pngs[itemImage][0], kind=itemKind) @@ -674,30 +674,30 @@ class ButtonPanelDemo(wx.Frame): self.titleBar.AddButton(btn) self.Bind(wx.EVT_BUTTON, self.OnButton, id=btn.GetId()) - + self.indices.append(btn.GetId()) if count in [0, 3, 5]: self.titleBar.AddSeparator() - + self.strings = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth"] - self.ChangeLayout() + self.ChangeLayout() self.Thaw() self.titleBar.DoLayout() - + def ChangeLayout(self): - + # Change the layout after a switch in ButtonPanel alignment self.Freeze() - + if self.alignment in [bp.BP_ALIGN_LEFT, bp.BP_ALIGN_RIGHT]: vSizer = wx.BoxSizer(wx.VERTICAL) else: vSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.mainPanel.SetSizer(vSizer) + + self.mainPanel.SetSizer(vSizer) vSizer.Add(self.titleBar, 0, wx.EXPAND) vSizer.Add((20, 20)) @@ -706,18 +706,18 @@ class ButtonPanelDemo(wx.Frame): vSizer.Layout() self.mainPanel.Layout() self.Thaw() - + def SetProperties(self): # No resetting if the user is using the Settings Panel if self.useredited: return - + # Sets the colours for the two demos: called only if the user didn't # modify the colours and sizes using the Settings Panel bpArt = self.titleBar.GetBPArt() - + if self.agwStyle & bp.BP_USE_GRADIENT: # set the colour the text is drawn with bpArt.SetColour(bp.BP_TEXT_COLOUR, wx.WHITE) @@ -733,11 +733,11 @@ class ButtonPanelDemo(wx.Frame): bpArt.SetColour(bp.BP_SEPARATOR_COLOUR, bp.BrightenColour(wx.Colour(60, 11, 112), 0.85)) bpArt.SetColour(bp.BP_SELECTION_BRUSH_COLOUR, wx.Colour(225, 225, 255)) - bpArt.SetColour(bp.BP_SELECTION_PEN_COLOUR, wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVECAPTION)) + bpArt.SetColour(bp.BP_SELECTION_PEN_COLOUR, wx.SystemSettings.GetColour(wx.SYS_COLOUR_ACTIVECAPTION)) else: - background = self.titleBar.GetBackgroundColour() + background = self.titleBar.GetBackgroundColour() bpArt.SetColour(bp.BP_TEXT_COLOUR, wx.BLUE) bpArt.SetColour(bp.BP_BORDER_COLOUR, bp.BrightenColour(background, 0.85)) @@ -748,30 +748,30 @@ class ButtonPanelDemo(wx.Frame): bpArt.SetColour(bp.BP_SELECTION_PEN_COLOUR, wx.Colour(206, 206, 195)) self.titleBar.SetStyle(self.agwStyle) - - + + def OnAlignment(self, event): - + # Here we change the alignment property of ButtonPanel current = event.GetId() item = self.GetMenuBar().FindItemById(current) alignment = getattr(bp, item.GetLabel()) self.alignment = alignment - self.ChangeLayout() + self.ChangeLayout() self.titleBar.SetAlignment(alignment) self.mainPanel.Layout() - + event.Skip() def OnDefaultStyle(self, event): - + # Restore the ButtonPanel default style (no gradient) self.agwStyle = bp.BP_DEFAULT_STYLE self.SetProperties() - event.Skip() + event.Skip() def OnGradientStyle(self, event): @@ -780,11 +780,11 @@ class ButtonPanelDemo(wx.Frame): self.agwStyle = bp.BP_USE_GRADIENT self.SetProperties() - event.Skip() + event.Skip() def OnDefaultDemo(self, event): - + # Reload the default startup demo self.CreateButtons() event.Skip() @@ -795,13 +795,13 @@ class ButtonPanelDemo(wx.Frame): # Reload the button-only demo self.ButtonOnly() event.Skip() - - + + def OnButton(self, event): btn = event.GetId() indx = self.indices.index(btn) - + self.logtext.AppendText("Event Fired From " + self.strings[indx] + " Button\n") event.Skip() @@ -810,9 +810,9 @@ class ButtonPanelDemo(wx.Frame): dlg = wx.TextEntryDialog(self, "Enter The Text You Wish To Display On The Bar (Clear If No Text):", "Set Text", self.titleBar.GetBarText()) - + if dlg.ShowModal() == wx.ID_OK: - + val = dlg.GetValue() self.titleBar.SetBarText(val) self.titleBar.DoLayout() @@ -831,7 +831,7 @@ class ButtonPanelDemo(wx.Frame): def OnClose(self, event): - + self.Destroy() event.Skip() @@ -845,11 +845,11 @@ class ButtonPanelDemo(wx.Frame): "andrea.gavana@gmail.com\n" + "andrea.gavana@maerskoil.com\n\n" + \ "Based On Eran C++ Implementation (wxWidgets Forum).\n\n" + \ "Welcome To wxPython " + wx.VERSION_STRING + "!!" - + dlg = wx.MessageDialog(self, msg, "ButtonPanel wxPython Demo", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() - dlg.Destroy() + dlg.Destroy() #---------------------------------------------------------------------- @@ -877,15 +877,12 @@ def runTest(frame, nb, log): #---------------------------------------------------------------------- - overview = bp.__doc__ - if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) - diff --git a/demo/agw/FlatMenu.py b/demo/agw/FlatMenu.py index e3d044a5..fde6812f 100644 --- a/demo/agw/FlatMenu.py +++ b/demo/agw/FlatMenu.py @@ -27,7 +27,7 @@ except ImportError: # if it's not there locally, try the wxPython lib. import images if wx.VERSION >= (2,7,0,0): - import wx.aui as AUI + import wx.lib.agw.aui as AUI AuiPaneInfo = AUI.AuiPaneInfo AuiManager = AUI.AuiManager _hasAUI = True @@ -76,14 +76,14 @@ def switchRGBtoBGR(colour): def CreateBackgroundBitmap(): mem_dc = wx.MemoryDC() - bmp = wx.EmptyBitmap(200, 300) + bmp = wx.Bitmap(200, 300) mem_dc.SelectObject(bmp) mem_dc.Clear() - + # colour the menu face with background colour - top = wx.NamedColour("blue") - bottom = wx.NamedColour("light blue") + top = wx.Colour("blue") + bottom = wx.Colour("light blue") filRect = wx.Rect(0, 0, 200, 300) mem_dc.GradientFillConcentric(filRect, top, bottom, wx.Point(100, 150)) @@ -96,7 +96,7 @@ def CreateBackgroundBitmap(): class FM_MyRenderer(FM.FMRenderer): """ My custom style. """ - + def __init__(self): FM.FMRenderer.__init__(self) @@ -104,13 +104,13 @@ class FM_MyRenderer(FM.FMRenderer): def DrawMenuButton(self, dc, rect, state): """Draws the highlight on a FlatMenu""" - + self.DrawButton(dc, rect, state) - - + + def DrawMenuBarButton(self, dc, rect, state): """Draws the highlight on a FlatMenuBar""" - + self.DrawButton(dc, rect, state) @@ -172,17 +172,17 @@ class FlatMenuDemo(wx.Frame): wx.NO_FULL_REPAINT_ON_RESIZE) self.SetIcon(images.Mondrian.GetIcon()) - wx.SystemOptions_SetOption("msw.remap", "0") + wx.SystemOptions.SetOption("msw.remap", "0") self.SetTitle("FlatMenu wxPython Demo ;-D") if _hasAUI: self._mgr = AuiManager() self._mgr.SetManagedWindow(self) - + self._popUpMenu = None mainSizer = wx.BoxSizer(wx.VERTICAL) - + # Create a main panel and place some controls on it mainPanel = wx.Panel(self, wx.ID_ANY) @@ -198,7 +198,7 @@ class FlatMenuDemo(wx.Frame): # Add log window self.log = log - + hs = wx.BoxSizer(wx.HORIZONTAL) btn = wx.Button(mainPanel, wx.ID_ANY, "Press me for pop up menu!") hs.Add(btn, 0, wx.ALL, 5) @@ -210,11 +210,11 @@ class FlatMenuDemo(wx.Frame): hs.Add(btn, 0, wx.ALL, 5) panelSizer.Add(hs, 0, wx.ALL, 5) - + # Connect a button btn.Bind(wx.EVT_BUTTON, self.OnLongButtonClicked) - statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + statusbar = self.CreateStatusBar(2) statusbar.SetStatusWidths([-2, -1]) # statusbar fields statusbar_fields = [("FlatMenu wxPython Demo, Andrea Gavana @ 01 Nov 2006"), @@ -222,7 +222,7 @@ class FlatMenuDemo(wx.Frame): for i in range(len(statusbar_fields)): statusbar.SetStatusText(statusbar_fields[i], i) - + self.CreateMenu() self.ConnectEvents() @@ -235,14 +235,14 @@ class FlatMenuDemo(wx.Frame): # AUI support self._mgr.AddPane(mainPanel, AuiPaneInfo().Name("main_panel"). CenterPane()) - + self._mgr.AddPane(minibarPanel, AuiPaneInfo().Name("minibar_panel"). Caption("Minibar Preview").Right(). MinSize(wx.Size(150, 200))) - + self._mb.PositionAUI(self._mgr) self._mgr.Update() - + ArtManager.Get().SetMBVerticalGradient(True) ArtManager.Get().SetRaiseToolbar(False) @@ -250,8 +250,8 @@ class FlatMenuDemo(wx.Frame): self._mtb.Refresh() self.CenterOnScreen() - - + + def CreateMinibar(self, parent): # create mini toolbar self._mtb = FM.FlatMenuBar(parent, wx.ID_ANY, 16, 6, options = FM_OPT_SHOW_TOOLBAR|FM_OPT_MINIBAR) @@ -270,7 +270,7 @@ class FlatMenuDemo(wx.Frame): self._mtb.AddRadioTool(wx.ID_ANY, "Zoom In", viewMagZoomBmp) self._mtb.AddRadioTool(wx.ID_ANY, "Zoom Out", viewMagZoomOutBmp) - + def CreateMenu(self): # Create the menubar @@ -302,7 +302,7 @@ class FlatMenuDemo(wx.Frame): view2Bmp = wx.Bitmap(os.path.join(bitmapDir, "view_detailed.png"), wx.BITMAP_TYPE_PNG) view3Bmp = wx.Bitmap(os.path.join(bitmapDir, "view_icon.png"), wx.BITMAP_TYPE_PNG) view4Bmp = wx.Bitmap(os.path.join(bitmapDir, "view_multicolumn.png"), wx.BITMAP_TYPE_PNG) - + # Set an icon to the exit/help/transparency menu item exitImg = wx.Bitmap(os.path.join(bitmapDir, "exit-16.png"), wx.BITMAP_TYPE_PNG) helpImg = wx.Bitmap(os.path.join(bitmapDir, "help-16.png"), wx.BITMAP_TYPE_PNG) @@ -324,26 +324,26 @@ class FlatMenuDemo(wx.Frame): item = FM.FlatMenuItem(fileMenu, MENU_SAVE, "&Save File\tCtrl+S", "Save File", wx.ITEM_NORMAL) fileMenu.AppendItem(item) self._mb.AddTool(MENU_SAVE, "Save File", save_bmp) - + item = FM.FlatMenuItem(fileMenu, MENU_OPEN_FILE, "&Open File\tCtrl+O", "Open File", wx.ITEM_NORMAL) fileMenu.AppendItem(item) self._mb.AddTool(MENU_OPEN_FILE, "Open File", open_folder_bmp) self._mb.AddSeparator() # Toolbar separator - + item = FM.FlatMenuItem(fileMenu, MENU_NEW_FOLDER, "N&ew Folder\tCtrl+E", "New Folder", wx.ITEM_NORMAL) fileMenu.AppendItem(item) self._mb.AddTool(MENU_NEW_FOLDER, "New Folder",new_folder_bmp) self._mb.AddSeparator() # Toobar separator - + item = FM.FlatMenuItem(fileMenu, MENU_COPY, "&Copy\tCtrl+C", "Copy", wx.ITEM_NORMAL) fileMenu.AppendItem(item) self._mb.AddTool(MENU_COPY, "Copy", copy_bmp) - + item = FM.FlatMenuItem(fileMenu, MENU_CUT, "Cut\tCtrl+X", "Cut", wx.ITEM_NORMAL) fileMenu.AppendItem(item) self._mb.AddTool(MENU_CUT, "Cut", cut_bmp) - + item = FM.FlatMenuItem(fileMenu, MENU_PASTE, "Paste\tCtrl+V", "Paste", wx.ITEM_NORMAL, subMenuExit) fileMenu.AppendItem(item) self._mb.AddTool(MENU_PASTE, "Paste", paste_bmp) @@ -353,14 +353,14 @@ class FlatMenuDemo(wx.Frame): # Add a wx.ComboBox to FlatToolbar combo = wx.ComboBox(self._mb, -1, choices=["Hello", "World", "wxPython"]) self._mb.AddControl(combo) - + self._mb.AddSeparator() # Separator - + stext = wx.StaticText(self._mb, -1, "Hello") #stext.SetBackgroundStyle(wx.BG_STYLE_CUSTOM ) - + self._mb.AddControl(stext) - + self._mb.AddSeparator() # Separator # Add another couple of bitmaps @@ -368,7 +368,7 @@ class FlatMenuDemo(wx.Frame): self._mb.AddRadioTool(wx.ID_ANY, "View Icons", view2Bmp) self._mb.AddRadioTool(wx.ID_ANY, "View Details", view3Bmp) self._mb.AddRadioTool(wx.ID_ANY, "View Multicolumn", view4Bmp) - + # Add non-toolbar item item = FM.FlatMenuItem(subMenuExit, wx.ID_EXIT, "E&xit\tAlt+X", "Exit demo", wx.ITEM_NORMAL, None, exitImg) subMenuExit.AppendItem(item) @@ -380,11 +380,11 @@ class FlatMenuDemo(wx.Frame): item = FM.FlatMenuItem(styleMenu, MENU_STYLE_DEFAULT, "Menu style Default\tAlt+N", "Menu style Default", wx.ITEM_RADIO) styleMenu.AppendItem(item) item.Check(True) - + item = FM.FlatMenuItem(styleMenu, MENU_STYLE_MY, "Menu style Custom \tAlt+C", "Menu style Custom", wx.ITEM_RADIO) styleMenu.AppendItem(item) - item = FM.FlatMenuItem(styleMenu, MENU_STYLE_XP, "Menu style XP\tAlt+P", "Menu style XP", wx.ITEM_RADIO) + item = FM.FlatMenuItem(styleMenu, MENU_STYLE_XP, "Menu style XP\tAlt+P", "Menu style XP", wx.ITEM_RADIO) styleMenu.AppendItem(item) item = FM.FlatMenuItem(styleMenu, MENU_STYLE_2007, "Menu style 2007\tAlt+O", "Menu style 2007", wx.ITEM_RADIO) @@ -399,21 +399,21 @@ class FlatMenuDemo(wx.Frame): # Demonstrate how to set custom font and text colour to a FlatMenuItem item.SetFont(wx.Font(10, wx.SWISS, wx.ITALIC, wx.BOLD, False, "Courier New")) item.SetTextColour(wx.RED) - + item.Check(True) styleMenu.AppendItem(item) - + styleMenu.AppendSeparator() item = FM.FlatMenuItem(styleMenu, MENU_LCD_MONITOR, "Use LCD monitors option", "Instructs FlatMenu to use LCD drawings", wx.ITEM_CHECK) styleMenu.AppendItem(item) - + # Add some radio items styleMenu.AppendSeparator() # Add sub-menu to main menu item = FM.FlatMenuItem(styleMenu, wx.ID_ANY, "Sub-&menu radio items", "", wx.ITEM_NORMAL, subMenu1) styleMenu.AppendItem(item) item.SetContextMenu(context_menu) - + item = FM.FlatMenuItem(subMenu1, wx.ID_ANY, "Radio Item 1", "Radio Item 1", wx.ITEM_RADIO) subMenu1.AppendItem(item) @@ -431,10 +431,10 @@ class FlatMenuDemo(wx.Frame): editMenu.AppendItem(item) editMenu.AppendSeparator() - + item = FM.FlatMenuItem(editMenu, MENU_TRANSPARENCY, "Set FlatMenu transparency...", "Sets the FlatMenu transparency", wx.ITEM_NORMAL, None, ghostBmp) - + editMenu.AppendItem(item) # Add some dummy entries to the sub menu @@ -442,7 +442,7 @@ class FlatMenuDemo(wx.Frame): item = FM.FlatMenuItem(editMenu, 9001, "Sub-&menu items", "", wx.ITEM_NORMAL, subMenu) editMenu.AppendItem(item) - # Create the submenu items and add them + # Create the submenu items and add them item = FM.FlatMenuItem(subMenu, 9002, "&Sub-menu Item 1", "", wx.ITEM_NORMAL) subMenu.AppendItem(item) @@ -471,7 +471,7 @@ class FlatMenuDemo(wx.Frame): col = random.randint(0, 2) item.SetFont(fnt) item.SetTextColour(colours[col]) - + multipleMenu.AppendItem(item) multipleMenu.SetNumberColumns(2) @@ -487,7 +487,7 @@ class FlatMenuDemo(wx.Frame): helpMenu.AppendItem(item) fileMenu.SetBackgroundBitmap(CreateBackgroundBitmap()) - + # Add menu to the menu bar self._mb.Append(fileMenu, "&File") self._mb.Append(styleMenu, "&Style") @@ -513,25 +513,25 @@ class FlatMenuDemo(wx.Frame): self.Bind(FM.EVT_FLAT_MENU_ITEM_MOUSE_OVER, self.OnMouseOver, id=MENU_NEW_FILE) self.Bind(FM.EVT_FLAT_MENU_ITEM_MOUSE_OUT, self.OnMouseOut, id=MENU_NEW_FILE) - + self.Bind(wx.EVT_UPDATE_UI, self.OnFlatMenuCmdUI, id=20001, id2=20013) if "__WXMAC__" in wx.Platform: self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(FM.EVT_FLAT_MENU_RANGE, self.OnFileHistory, id=wx.ID_FILE1, id2=wx.ID_FILE9+1) - - + + def OnSize(self, event): - + self._mgr.Update() self.Layout() - + def OnQuit(self, event): if _hasAUI: self._mgr.UnInit() - + self.Destroy() @@ -548,19 +548,19 @@ class FlatMenuDemo(wx.Frame): btnSize = btn.GetSize() btnPt = btn.GetPosition() - # Since the btnPt (button position) is in client coordinates, + # Since the btnPt (button position) is in client coordinates, # and the menu coordinates is relative to screen we convert # the coords btnPt = btn.GetParent().ClientToScreen(btnPt) - # A nice feature with the Popup menu, is the ability to provide an + # A nice feature with the Popup menu, is the ability to provide an # object that we wish to handle the menu events, in this case we # pass 'self' # if we wish the menu to appear under the button, we provide its height self._popUpMenu.SetOwnerHeight(btnSize.y) self._popUpMenu.Popup(wx.Point(btnPt.x, btnPt.y), self) - + def OnLongButtonClicked(self, event): # Demonstrate using the wxFlatMenu without a menu bar @@ -573,20 +573,20 @@ class FlatMenuDemo(wx.Frame): # The menu should be positioned at the bottom left corner of the button. btnSize = btn.GetSize() - # btnPt is returned relative to its parent - # so, we need to convert it to screen + # btnPt is returned relative to its parent + # so, we need to convert it to screen btnPt = btn.GetPosition() btnPt = btn.GetParent().ClientToScreen(btnPt) # if we wish the menu to appear under the button, we provide its height self._longPopUpMenu.SetOwnerHeight(btnSize.y) self._longPopUpMenu.Popup(wx.Point(btnPt.x, btnPt.y), self) - + def CreatePopupMenu(self): if not self._popUpMenu: - + self._popUpMenu = FM.FlatMenu() #----------------------------------------------- # Flat Menu test @@ -616,10 +616,10 @@ class FlatMenuDemo(wx.Frame): menuItem = FM.FlatMenuItem(self._popUpMenu, 20004, "Sub-&menu item", "", wx.ITEM_NORMAL, subMenu) self._popUpMenu.AppendItem(menuItem) - # Create the submenu items and add them + # Create the submenu items and add them menuItem = FM.FlatMenuItem(subMenu, 20005, "&Sub-menu Item 1", "", wx.ITEM_NORMAL) subMenu.AppendItem(menuItem) - + menuItem = FM.FlatMenuItem(subMenu, 20006, "Su&b-menu Item 2", "", wx.ITEM_NORMAL) subMenu.AppendItem(menuItem) @@ -629,10 +629,10 @@ class FlatMenuDemo(wx.Frame): menuItem = FM.FlatMenuItem(subMenu, 20008, "Sub-menu Item 4", "", wx.ITEM_NORMAL) subMenu.AppendItem(menuItem) - # Create the submenu items and add them + # Create the submenu items and add them menuItem = FM.FlatMenuItem(subSubMenu, 20009, "Sub-menu Item 1", "", wx.ITEM_NORMAL) subSubMenu.AppendItem(menuItem) - + menuItem = FM.FlatMenuItem(subSubMenu, 20010, "Sub-menu Item 2", "", wx.ITEM_NORMAL) subSubMenu.AppendItem(menuItem) @@ -654,11 +654,11 @@ class FlatMenuDemo(wx.Frame): self._longPopUpMenu = FM.FlatMenu() sub = FM.FlatMenu() - + #----------------------------------------------- # Flat Menu test #----------------------------------------------- - + for ii in xrange(30): if ii == 0: menuItem = FM.FlatMenuItem(self._longPopUpMenu, wx.ID_ANY, "Menu Item #%ld"%(ii+1), "", wx.ITEM_NORMAL, sub) @@ -673,7 +673,7 @@ class FlatMenuDemo(wx.Frame): menuItem = FM.FlatMenuItem(self._longPopUpMenu, wx.ID_ANY, "Menu Item #%ld"%(ii+1)) self._longPopUpMenu.AppendItem(menuItem) - + # ------------------------------------------ # Event handlers # ------------------------------------------ @@ -681,7 +681,7 @@ class FlatMenuDemo(wx.Frame): def OnStyle(self, event): eventId = event.GetId() - + if eventId == MENU_STYLE_DEFAULT: self._mb.GetRendererManager().SetTheme(FM.StyleDefault) elif eventId == MENU_STYLE_2007: @@ -698,17 +698,17 @@ class FlatMenuDemo(wx.Frame): self._mb.Refresh() self._mtb.Refresh() self.Update() - + def OnShowCustom(self, event): self._mb.ShowCustomize(event.IsChecked()) - + def OnLCDMonitor(self, event): self._mb.SetLCDMonitor(event.IsChecked()) - + def OnTransparency(self, event): @@ -722,7 +722,7 @@ class FlatMenuDemo(wx.Frame): value = dlg.GetValue() dlg.Destroy() - + try: value = int(value) except: @@ -736,20 +736,20 @@ class FlatMenuDemo(wx.Frame): wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() - + ArtManager.Get().SetTransparency(value) - + def OnMouseOver(self, event): self.log.write("Received Flat menu mouse enter ID: %d\n"%(event.GetId())) - + def OnMouseOut(self, event): - + self.log.write("Received Flat menu mouse leave ID: %d\n"%(event.GetId())) - - + + def OnFlatMenuCmd(self, event): self.log.write("Received Flat menu command event ID: %d\n"%(event.GetId())) @@ -767,9 +767,9 @@ class FlatMenuDemo(wx.Frame): userString = "" if dlg.ShowModal() == wx.ID_OK: userString = dlg.GetValue() - + dlg.Destroy() - + return userString @@ -798,12 +798,12 @@ class FlatMenuDemo(wx.Frame): def OnEdit(self, event): - + if event.GetId() == MENU_REMOVE_MENU: idxStr = self.GetStringFromUser("Insert menu index to remove:") if idxStr.strip() != "": - + idx = int(idxStr) self._mb.Remove(idx) @@ -826,7 +826,7 @@ class FlatMenuDemo(wx.Frame): "to Andrea Gavana at the following email addresses:\n\n" + \ "andrea.gavana@gmail.com\nandrea.gavana@maerskoil.com\n\n" + \ "Welcome to wxPython " + wx.VERSION_STRING + "!!" - + dlg = wx.MessageDialog(self, msg, "FlatMenu wxPython Demo", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() diff --git a/demo/agw/FlatNotebook.py b/demo/agw/FlatNotebook.py index 8ce497f7..a33fd7de 100644 --- a/demo/agw/FlatNotebook.py +++ b/demo/agw/FlatNotebook.py @@ -85,7 +85,7 @@ class FlatNotebookDemo(wx.Frame): self._ImageList.Add(images._book_green.GetBitmap()) self._ImageList.Add(images._book_blue.GetBitmap()) - self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-2, -1]) # statusbar fields statusbar_fields = [("FlatNotebook wxPython Demo, Andrea Gavana @ 02 Oct 2006"), @@ -104,7 +104,7 @@ class FlatNotebookDemo(wx.Frame): self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnPageClosing) self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_DROPPED_FOREIGN, self.OnForeignDrop) self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_DROPPED, self.OnDrop) - + self.Bind(wx.EVT_UPDATE_UI, self.OnDropDownArrowUI, id=MENU_USE_DROP_ARROW_BUTTON) self.Bind(wx.EVT_UPDATE_UI, self.OnHideNavigationButtonsUI, id=MENU_HIDE_NAV_BUTTONS) self.Bind(wx.EVT_UPDATE_UI, self.OnAllowForeignDndUI, id=MENU_ALLOW_FOREIGN_DND) @@ -119,139 +119,139 @@ class FlatNotebookDemo(wx.Frame): item = wx.MenuItem(self._fileMenu, wx.ID_ANY, "&Close\tCtrl-Q", "Close demo window") self.Bind(wx.EVT_MENU, self.OnQuit, item) - self._fileMenu.AppendItem(item) + self._fileMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_EDIT_ADD_PAGE, "New Page\tCtrl+N", "Add New Page") self.Bind(wx.EVT_MENU, self.OnAddPage, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_EDIT_DELETE_PAGE, "Delete Page\tCtrl+F4", "Delete Page") self.Bind(wx.EVT_MENU, self.OnDeletePage, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_EDIT_DELETE_ALL, "Delete All Pages", "Delete All Pages") self.Bind(wx.EVT_MENU, self.OnDeleteAll, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_EDIT_SET_SELECTION, "Set Selection", "Set Selection") self.Bind(wx.EVT_MENU, self.OnSetSelection, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_EDIT_ADVANCE_SELECTION_FWD, "Advance Selection Forward", "Advance Selection Forward") self.Bind(wx.EVT_MENU, self.OnAdvanceSelectionFwd, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_EDIT_ADVANCE_SELECTION_BACK, "Advance Selection Backward", "Advance Selection Backward") self.Bind(wx.EVT_MENU, self.OnAdvanceSelectionBack, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_SET_ALL_TABS_SHAPE_ANGLE, "Set an inclination of tab header borders", "Set the shape of tab header") self.Bind(wx.EVT_MENU, self.OnSetAllPagesShapeAngle, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_SET_PAGE_IMAGE_INDEX, "Set image index of selected page", "Set image index") self.Bind(wx.EVT_MENU, self.OnSetPageImage, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_SHOW_IMAGES, "Show Images", "Show Images", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnShowImages, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) styleMenu = wx.Menu() item = wx.MenuItem(styleMenu, MENU_USE_DEFAULT_STYLE, "Use Default Style", "Use VC71 Style", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.OnDefaultStyle, item) - styleMenu.AppendItem(item) + styleMenu.Append(item) item = wx.MenuItem(styleMenu, MENU_USE_VC71_STYLE, "Use VC71 Style", "Use VC71 Style", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.OnVC71Style, item) - styleMenu.AppendItem(item) + styleMenu.Append(item) item = wx.MenuItem(styleMenu, MENU_USE_VC8_STYLE, "Use VC8 Style", "Use VC8 Style", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.OnVC8Style, item) - styleMenu.AppendItem(item) + styleMenu.Append(item) item = wx.MenuItem(styleMenu, MENU_USE_FANCY_STYLE, "Use Fancy Style", "Use Fancy Style", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.OnFancyStyle, item) - styleMenu.AppendItem(item) + styleMenu.Append(item) item = wx.MenuItem(styleMenu, MENU_USE_FF2_STYLE, "Use Firefox 2 Style", "Use Firefox 2 Style", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.OnFF2Style, item) - styleMenu.AppendItem(item) - + styleMenu.Append(item) + item = wx.MenuItem(styleMenu, MENU_USE_RIBBON_STYLE, "Use Ribbon Style", "Use Ribbon Style", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.OnRibbonStyle, item) - styleMenu.AppendItem(item) + styleMenu.Append(item) - self._visualMenu.AppendMenu(wx.ID_ANY, "Tabs Style", styleMenu) + self._visualMenu.Append(wx.ID_ANY, "Tabs Style", styleMenu) item = wx.MenuItem(self._visualMenu, MENU_SELECT_GRADIENT_COLOUR_FROM, "Select fancy tab style 'from' colour", "Select fancy tab style 'from' colour") - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item = wx.MenuItem(self._visualMenu, MENU_SELECT_GRADIENT_COLOUR_TO, "Select fancy tab style 'to' colour", "Select fancy tab style 'to' colour") - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item = wx.MenuItem(self._visualMenu, MENU_SELECT_GRADIENT_COLOUR_BORDER, "Select fancy tab style 'border' colour", "Select fancy tab style 'border' colour") - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) - self._editMenu.AppendSeparator() + self._editMenu.AppendSeparator() self.Bind(wx.EVT_MENU_RANGE, self.OnSelectColour, id=MENU_SELECT_GRADIENT_COLOUR_FROM, - id2=MENU_SELECT_GRADIENT_COLOUR_BORDER) + id2=MENU_SELECT_GRADIENT_COLOUR_BORDER) item = wx.MenuItem(self._editMenu, MENU_HIDE_ON_SINGLE_TAB, "Hide Page Container when only one Tab", "Hide Page Container when only one Tab", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnStyle, item) - self._editMenu.AppendItem(item) - + self._editMenu.Append(item) + item = wx.MenuItem(self._editMenu, MENU_HIDE_TABS, "Hide Tabs", "Hide Page Container allowing only keyboard navigation", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnStyle, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_NO_TABS_FOCUS, "No focus on notebook tabs", "No focus on notebook tabs, only pages", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnStyle, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_HIDE_NAV_BUTTONS, "Hide Navigation Buttons", "Hide Navigation Buttons", wx.ITEM_CHECK) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_HIDE_X, "Hide X Button", "Hide X Button", wx.ITEM_CHECK) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_SMART_TABS, "Smart tabbing", "Smart tabbing", wx.ITEM_CHECK) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) self.Bind(wx.EVT_MENU, self.OnSmartTabs, item) item.Check(False) item = wx.MenuItem(self._editMenu, MENU_USE_DROP_ARROW_BUTTON, "Use drop down button for tab navigation", "Use drop down arrow for quick tab navigation", wx.ITEM_CHECK) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) self.Bind(wx.EVT_MENU, self.OnDropDownArrow, item) item.Check(False) self._editMenu.AppendSeparator() item = wx.MenuItem(self._editMenu, MENU_TILE_HORIZONTALLY, "Tile pages horizontally", "Tile all the panels in an horizontal sizer", wx.ITEM_RADIO) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) self.Bind(wx.EVT_MENU, self.OnTile, item) - + item = wx.MenuItem(self._editMenu, MENU_TILE_VERTICALLY, "Tile pages vertically", "Tile all the panels in a vertical sizer", wx.ITEM_RADIO) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) self.Bind(wx.EVT_MENU, self.OnTile, item) item = wx.MenuItem(self._editMenu, MENU_TILE_NONE, "No tiling", "No tiling, standard FlatNotebook behaviour", wx.ITEM_RADIO) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) self.Bind(wx.EVT_MENU, self.OnTile, item) item.Check(True) @@ -260,95 +260,95 @@ class FlatNotebookDemo(wx.Frame): item = wx.MenuItem(self._editMenu, wx.ID_ANY, "Use custom page", "Shows a custom page when the main notebook has no pages left", wx.ITEM_CHECK) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) self.Bind(wx.EVT_MENU, self.OnCustomPanel, item) self._editMenu.AppendSeparator() - + item = wx.MenuItem(self._editMenu, MENU_USE_MOUSE_MIDDLE_BTN, "Use Mouse Middle Button as 'X' button", "Use Mouse Middle Button as 'X' button", wx.ITEM_CHECK) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_DCLICK_CLOSES_TAB, "Mouse double click closes tab", "Mouse double click closes tab", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnDClickCloseTab, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item.Check(False) self._editMenu.AppendSeparator() item = wx.MenuItem(self._editMenu, MENU_USE_BOTTOM_TABS, "Use Bottoms Tabs", "Use Bottoms Tabs", wx.ITEM_CHECK) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) self.Bind(wx.EVT_MENU_RANGE, self.OnStyle, id=MENU_HIDE_X, id2=MENU_USE_BOTTOM_TABS) item = wx.MenuItem(self._editMenu, MENU_ENABLE_TAB, "Enable Tab", "Enable Tab") self.Bind(wx.EVT_MENU, self.OnEnableTab, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_DISABLE_TAB, "Disable Tab", "Disable Tab") self.Bind(wx.EVT_MENU, self.OnDisableTab, item) - self._editMenu.AppendItem(item) + self._editMenu.Append(item) item = wx.MenuItem(self._editMenu, MENU_ENABLE_DRAG_N_DROP, "Enable Drag And Drop of Tabs", "Enable Drag And Drop of Tabs", wx.ITEM_CHECK) - self.Bind(wx.EVT_MENU, self.OnEnableDrag, item) - self._editMenu.AppendItem(item) + self.Bind(wx.EVT_MENU, self.OnEnableDrag, item) + self._editMenu.Append(item) item.Check(False) item = wx.MenuItem(self._editMenu, MENU_ALLOW_FOREIGN_DND, "Enable Drag And Drop of Tabs from foreign notebooks", "Enable Drag And Drop of Tabs from foreign notebooks", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnAllowForeignDnd, item) - self._editMenu.AppendItem(item) - item.Check(False); + self._editMenu.Append(item) + item.Check(False); item = wx.MenuItem(self._visualMenu, MENU_DRAW_BORDER, "Draw Border around tab area", "Draw Border around tab area", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnStyle, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item.Check(True) item = wx.MenuItem(self._visualMenu, MENU_DRAW_TAB_X, "Draw X button On Active Tab", "Draw X button On Active Tab", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnDrawTabX, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item = wx.MenuItem(self._visualMenu, MENU_SET_ACTIVE_TAB_COLOUR, "Select Active Tab Colour", "Select Active Tab Colour") self.Bind(wx.EVT_MENU, self.OnSelectColour, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item = wx.MenuItem(self._visualMenu, MENU_SET_TAB_AREA_COLOUR, "Select Tab Area Colour", "Select Tab Area Colour") self.Bind(wx.EVT_MENU, self.OnSelectColour, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item = wx.MenuItem(self._visualMenu, MENU_SET_ACTIVE_TEXT_COLOUR, "Select active tab text colour", "Select active tab text colour") self.Bind(wx.EVT_MENU, self.OnSelectColour, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item = wx.MenuItem(self._visualMenu, MENU_SELECT_NONACTIVE_TEXT_COLOUR, "Select NON-active tab text colour", "Select NON-active tab text colour") self.Bind(wx.EVT_MENU, self.OnSelectColour, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item = wx.MenuItem(self._visualMenu, MENU_GRADIENT_BACKGROUND, "Use Gradient Colouring for tab area", "Use Gradient Colouring for tab area", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnGradientBack, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item.Check(False) item = wx.MenuItem(self._visualMenu, MENU_COLOURFUL_TABS, "Colourful tabs", "Colourful tabs", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.OnColourfulTabs, item) - self._visualMenu.AppendItem(item) + self._visualMenu.Append(item) item.Check(False) help_menu = wx.Menu() item = wx.MenuItem(help_menu, wx.ID_ANY, "About...", "Shows The About Dialog") self.Bind(wx.EVT_MENU, self.OnAbout, item) - help_menu.AppendItem(item) + help_menu.Append(item) self._menuBar.Append(self._fileMenu, "&File") self._menuBar.Append(self._editMenu, "&Edit") @@ -363,7 +363,7 @@ class FlatNotebookDemo(wx.Frame): self._rmenu = wx.Menu() item = wx.MenuItem(self._rmenu, MENU_EDIT_DELETE_PAGE, "Close Tab\tCtrl+F4", "Close Tab") - self._rmenu.AppendItem(item) + self._rmenu.Append(item) def LayoutItems(self): @@ -376,19 +376,19 @@ class FlatNotebookDemo(wx.Frame): self.book = FNB.FlatNotebook(self, wx.ID_ANY, agwStyle=bookStyle) bookStyle &= ~(FNB.FNB_NODRAG) - bookStyle |= FNB.FNB_ALLOW_FOREIGN_DND + bookStyle |= FNB.FNB_ALLOW_FOREIGN_DND self.secondBook = FNB.FlatNotebook(self, wx.ID_ANY, agwStyle=bookStyle) # Set right click menu to the notebook self.book.SetRightClickMenu(self._rmenu) - # Set the image list + # Set the image list self.book.SetImageList(self._ImageList) mainSizer.Add(self.book, 6, wx.EXPAND) # Add spacer between the books spacer = wx.Panel(self, -1) - spacer.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE)) + spacer.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE)) mainSizer.Add(spacer, 0, wx.ALL | wx.EXPAND) mainSizer.Add(self.secondBook, 2, wx.EXPAND) @@ -396,13 +396,13 @@ class FlatNotebookDemo(wx.Frame): # Add some pages to the second notebook self.Freeze() - text = wx.TextCtrl(self.secondBook, -1, "Second Book Page 1\n", style=wx.TE_MULTILINE|wx.TE_READONLY) + text = wx.TextCtrl(self.secondBook, -1, "Second Book Page 1\n", style=wx.TE_MULTILINE|wx.TE_READONLY) self.secondBook.AddPage(text, "Second Book Page 1") text = wx.TextCtrl(self.secondBook, -1, "Second Book Page 2\n", style=wx.TE_MULTILINE|wx.TE_READONLY) self.secondBook.AddPage(text, "Second Book Page 2") - self.Thaw() + self.Thaw() mainSizer.Layout() self.SendSizeEvent() @@ -414,7 +414,7 @@ class FlatNotebookDemo(wx.Frame): eventid = event.GetId() if eventid == MENU_HIDE_NAV_BUTTONS: - if event.IsChecked(): + if event.IsChecked(): # Hide the navigation buttons style |= FNB.FNB_NO_NAV_BUTTONS else: @@ -429,9 +429,9 @@ class FlatNotebookDemo(wx.Frame): style |= FNB.FNB_HIDE_ON_SINGLE_TAB else: style &= ~(FNB.FNB_HIDE_ON_SINGLE_TAB) - + self.book.SetAGWWindowStyleFlag(style) - + elif eventid == MENU_HIDE_TABS: if event.IsChecked(): # Hide the tabs @@ -462,7 +462,7 @@ class FlatNotebookDemo(wx.Frame): elif eventid == MENU_USE_MOUSE_MIDDLE_BTN: if event.IsChecked(): - style |= FNB.FNB_MOUSE_MIDDLE_CLOSES_TABS + style |= FNB.FNB_MOUSE_MIDDLE_CLOSES_TABS else: if style & FNB.FNB_MOUSE_MIDDLE_CLOSES_TABS: style ^= FNB.FNB_MOUSE_MIDDLE_CLOSES_TABS @@ -509,7 +509,7 @@ class FlatNotebookDemo(wx.Frame): self.log.write('Foreign drop received\n') self.log.write('new NB: %s || old NB: %s\n' % (event.GetNotebook(), event.GetOldNotebook())) self.log.write('new tab: %s || old tab: %s\n' % (event.GetSelection(), event.GetOldSelection())) - + def OnDrop(self, event): @@ -555,7 +555,7 @@ class FlatNotebookDemo(wx.Frame): style |= FNB.FNB_VC8 self.book.SetAGWWindowStyleFlag(style) - + def OnRibbonStyle(self, event): style = self.book.GetAGWWindowStyleFlag() @@ -591,7 +591,7 @@ class FlatNotebookDemo(wx.Frame): style |= FNB.FNB_FANCY_TABS self.book.SetAGWWindowStyleFlag(style) - + def OnSelectColour(self, event): @@ -667,7 +667,7 @@ class FlatNotebookDemo(wx.Frame): if dlg.ShowModal() == wx.ID_OK: val = dlg.GetValue() - self.book.EnableTab(int(val)) + self.book.EnableTab(int(val)) def OnDisableTab(self, event): @@ -677,7 +677,7 @@ class FlatNotebookDemo(wx.Frame): if dlg.ShowModal() == wx.ID_OK: val = dlg.GetValue() - self.book.EnableTab(int(val), False) + self.book.EnableTab(int(val), False) def OnEnableDrag(self, event): @@ -685,7 +685,7 @@ class FlatNotebookDemo(wx.Frame): style = self.book.GetAGWWindowStyleFlag() style2 = self.secondBook.GetAGWWindowStyleFlag() - if event.IsChecked(): + if event.IsChecked(): if style & FNB.FNB_NODRAG: style ^= FNB.FNB_NODRAG if style2 & FNB.FNB_NODRAG: @@ -698,16 +698,16 @@ class FlatNotebookDemo(wx.Frame): self.secondBook.SetAGWWindowStyleFlag(style2) - def OnAllowForeignDnd(self, event): + def OnAllowForeignDnd(self, event): style = self.book.GetAGWWindowStyleFlag() if event.IsChecked(): - style |= FNB.FNB_ALLOW_FOREIGN_DND + style |= FNB.FNB_ALLOW_FOREIGN_DND else: style &= ~(FNB.FNB_ALLOW_FOREIGN_DND) self.book.SetAGWWindowStyleFlag(style) - self.book.Refresh() + self.book.Refresh() def OnSetAllPagesShapeAngle(self, event): @@ -763,7 +763,7 @@ class FlatNotebookDemo(wx.Frame): style |= FNB.FNB_X_ON_TAB else: if style & FNB.FNB_X_ON_TAB: - style ^= FNB.FNB_X_ON_TAB + style ^= FNB.FNB_X_ON_TAB self.book.SetAGWWindowStyleFlag(style) @@ -771,10 +771,10 @@ class FlatNotebookDemo(wx.Frame): def OnDClickCloseTab(self, event): style = self.book.GetAGWWindowStyleFlag() - if event.IsChecked(): + if event.IsChecked(): style |= FNB.FNB_DCLICK_CLOSES_TABS else: - style &= ~(FNB.FNB_DCLICK_CLOSES_TABS) + style &= ~(FNB.FNB_DCLICK_CLOSES_TABS) self.book.SetAGWWindowStyleFlag(style) @@ -842,7 +842,7 @@ class FlatNotebookDemo(wx.Frame): self.book.Tile(wx.VERTICAL) else: self.book.Tile(None) - + def OnCustomPanel(self, event): @@ -865,7 +865,7 @@ class FlatNotebookDemo(wx.Frame): event.Check((style & FNB.FNB_DROPDOWN_TABS_LIST and [True] or [False])[0]) - def OnAllowForeignDndUI(self, event): + def OnAllowForeignDndUI(self, event): style = self.book.GetAGWWindowStyleFlag() event.Enable((style & FNB.FNB_NODRAG and [False] or [True])[0]) @@ -884,7 +884,7 @@ class FlatNotebookDemo(wx.Frame): dlg = wx.MessageDialog(self, msg, "FlatNotebook wxPython Demo", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() - dlg.Destroy() + dlg.Destroy() class LogoPanel(wx.Panel): @@ -901,7 +901,7 @@ class LogoPanel(wx.Panel): self.normalfont = wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, True) self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) - + self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnSize) @@ -910,38 +910,38 @@ class LogoPanel(wx.Panel): event.Skip() self.Refresh() - + def OnPaint(self, event): - + dc = wx.AutoBufferedPaintDC(self) - self.DoDrawing(dc) - + self.DoDrawing(dc) + def DoDrawing(self, dc): dc.SetBackground(wx.WHITE_BRUSH) dc.Clear() - + w, h = self.GetClientSize() bmpW, bmpH = self.bmp.GetWidth(), self.bmp.GetHeight() xpos, ypos = int((w - bmpW)/2), int((h - bmpH)/2) - + dc.DrawBitmap(self.bmp, xpos, ypos, True) dc.SetFont(self.bigfont) dc.SetTextForeground(wx.BLUE) dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.SetPen(wx.Pen(wx.BLUE, 2)) - + tw, th = dc.GetTextExtent("FlatNotebook") xpos = int((w - tw)/2) ypos = int(h/3) dc.DrawRoundedRectangle(xpos-5, ypos-3, tw+10, th+6, 3) dc.DrawText("FlatNotebook", xpos, ypos) - + dc.SetFont(self.normalfont) dc.SetTextForeground(wx.RED) tw, th = dc.GetTextExtent("Andrea Gavana") @@ -952,9 +952,9 @@ class LogoPanel(wx.Panel): xpos = int((w - tw)/2) ypos = int(2*h/3 + 3*th/2) - + dc.DrawText("02 Oct 2006", xpos, ypos) - + #--------------------------------------------------------------------------- diff --git a/demo/agw/FloatSpin.py b/demo/agw/FloatSpin.py index eac6ff0e..b4a6f20c 100644 --- a/demo/agw/FloatSpin.py +++ b/demo/agw/FloatSpin.py @@ -22,7 +22,7 @@ except ImportError: # if it's not there locally, try the wxPython lib. class FloatSpinDemo(wx.Panel): def __init__(self, parent, log): - + wx.Panel.__init__(self, parent) self.log = log @@ -32,12 +32,12 @@ class FloatSpinDemo(wx.Panel): self.sizer_8_staticbox = wx.StaticBox(self.mainpanel, -1, "Example 4") self.sizer_4_staticbox = wx.StaticBox(self.mainpanel, -1, "Example 1") self.helptext = wx.StaticText(self.mainpanel, -1, "Welcome to the FloatSpin Demo") - + self.floatspin1 = FS.FloatSpin(self.mainpanel, -1, min_val=0, max_val=1, increment=0.01, value=0.1, agwStyle=FS.FS_LEFT) self.floatspin1.SetFormat("%f") self.floatspin1.SetDigits(2) - + self.setvalue1 = wx.Button(self.mainpanel, -1, "Set Value") self.textctrlvalue1 = wx.TextCtrl(self.mainpanel, -1, "0.0") self.setdigits1 = wx.Button(self.mainpanel, -1, "Set Digits") @@ -53,7 +53,7 @@ class FloatSpinDemo(wx.Panel): increment=0.1, agwStyle=FS.FS_RIGHT) self.floatspin2.SetFormat("%e") self.floatspin2.SetDigits(4) - + self.setvalue2 = wx.Button(self.mainpanel, -1, "Set Value") self.textctrlvalue2 = wx.TextCtrl(self.mainpanel, -1, "0.0") self.setdigits2 = wx.Button(self.mainpanel, -1, "Set Digits") @@ -69,7 +69,7 @@ class FloatSpinDemo(wx.Panel): increment=0.0001, agwStyle=FS.FS_CENTRE) self.floatspin3.SetFormat("%f") self.floatspin3.SetDigits(5) - + self.setvalue3 = wx.Button(self.mainpanel, -1, "Set Value") self.textctrlvalue3 = wx.TextCtrl(self.mainpanel, -1, "0.01") self.setdigits3 = wx.Button(self.mainpanel, -1, "Set Digits") @@ -85,7 +85,7 @@ class FloatSpinDemo(wx.Panel): increment=0.1, agwStyle=FS.FS_READONLY) self.floatspin4.SetFormat("%G") self.floatspin4.SetDigits(3) - + self.setvalue4 = wx.Button(self.mainpanel, -1, "Set Value") self.textctrlvalue4 = wx.TextCtrl(self.mainpanel, -1, "0.0") self.setdigits4 = wx.Button(self.mainpanel, -1, "Set Digits") @@ -118,19 +118,19 @@ class FloatSpinDemo(wx.Panel): self.SetProperties() self.DoLayout() self.BindEvents() - + def SetProperties(self): - + self.helptext.SetFont(wx.Font(10, wx.MODERN, wx.NORMAL, wx.BOLD, 0, "Verdana")) self.radioformat1.SetSelection(0) self.radioformat2.SetSelection(2) self.radioformat3.SetSelection(0) self.radioformat4.SetSelection(5) - + def DoLayout(self): - + mainsizer = wx.BoxSizer(wx.VERTICAL) panelsizer = wx.BoxSizer(wx.VERTICAL) sizer_6 = wx.BoxSizer(wx.HORIZONTAL) @@ -185,7 +185,7 @@ class FloatSpinDemo(wx.Panel): wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) subright13.Add(self.textctrlincr1, 1, wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_HORIZONTAL| wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 3) - right1.Add(subright13, 0, wx.EXPAND, 0) + right1.Add(subright13, 0, wx.EXPAND, 0) right1.Add((0, 5), 0, wx.ADJUST_MINSIZE, 0) right1.Add(self.setfont1, 0, wx.LEFT|wx.TOP|wx.BOTTOM|wx.ADJUST_MINSIZE, 3) right1.Add((0,1), 1, wx.EXPAND) @@ -217,7 +217,7 @@ class FloatSpinDemo(wx.Panel): wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) subright23.Add(self.textctrlincr2, 1, wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_HORIZONTAL| wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 3) - right2.Add(subright23, 0, wx.EXPAND, 0) + right2.Add(subright23, 0, wx.EXPAND, 0) right2.Add((0, 5), 0, wx.ADJUST_MINSIZE, 0) right2.Add(self.setfont2, 0, wx.LEFT|wx.TOP|wx.BOTTOM|wx.ADJUST_MINSIZE, 3) right2.Add((0,1), 1, wx.EXPAND) @@ -250,7 +250,7 @@ class FloatSpinDemo(wx.Panel): wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) subright33.Add(self.textctrlincr3, 1, wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_HORIZONTAL| wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 3) - right3.Add(subright33, 0, wx.EXPAND, 0) + right3.Add(subright33, 0, wx.EXPAND, 0) right3.Add((0, 5), 0, wx.ADJUST_MINSIZE, 0) right3.Add(self.setfont3, 0, wx.LEFT|wx.TOP|wx.BOTTOM|wx.ADJUST_MINSIZE, 3) right3.Add((0,1), 1, wx.EXPAND) @@ -282,7 +282,7 @@ class FloatSpinDemo(wx.Panel): wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) subright43.Add(self.textctrlincr4, 1, wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_HORIZONTAL| wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 3) - right4.Add(subright43, 0, wx.EXPAND, 0) + right4.Add(subright43, 0, wx.EXPAND, 0) right4.Add((0, 5), 0, wx.ADJUST_MINSIZE, 0) right4.Add(self.setfont4, 0, wx.LEFT|wx.TOP|wx.BOTTOM|wx.ADJUST_MINSIZE, 3) right4.Add((0,1), 1, wx.EXPAND) @@ -296,7 +296,7 @@ class FloatSpinDemo(wx.Panel): mainsizer.Add(self.mainpanel, 1, wx.EXPAND, 0) self.SetSizer(mainsizer) mainsizer.Layout() - + def BindEvents(self): @@ -325,7 +325,7 @@ class FloatSpinDemo(wx.Panel): self.floatspin2.Bind(FS.EVT_FLOATSPIN, self.OnFloatSpin) self.floatspin3.Bind(FS.EVT_FLOATSPIN, self.OnFloatSpin) self.floatspin4.Bind(FS.EVT_FLOATSPIN, self.OnFloatSpin) - + def OnSetValue(self, event): @@ -345,9 +345,9 @@ class FloatSpinDemo(wx.Panel): return floatspin.SetValue(value) - + event.Skip() - + def OnSetDigits(self, event): @@ -367,9 +367,9 @@ class FloatSpinDemo(wx.Panel): return floatspin.SetDigits(value) - + event.Skip() - + def OnChangeFormat(self, event): @@ -379,9 +379,9 @@ class FloatSpinDemo(wx.Panel): fmt = radio.GetStringSelection() floatspin.SetFormat(fmt) - + event.Skip() - + def OnSetIncrement(self, event): @@ -410,7 +410,7 @@ class FloatSpinDemo(wx.Panel): dlg.ShowModal() dlg.Destroy() return - + event.Skip() @@ -419,13 +419,13 @@ class FloatSpinDemo(wx.Panel): btn = event.GetEventObject() indx = self.fontbuttons.index(btn) floatspin = self.floatspins[indx] - + data = wx.FontData() data.EnableEffects(True) data.SetInitialFont(floatspin.GetFont()) dlg = wx.FontDialog(self, data) - + if dlg.ShowModal() == wx.ID_OK: data = dlg.GetFontData() font = data.GetChosenFont() @@ -433,17 +433,17 @@ class FloatSpinDemo(wx.Panel): floatspin.SetFont(font) floatspin.GetTextCtrl().SetForegroundColour(colour) floatspin.Refresh() - + # Don't destroy the dialog until you get everything you need from the # dialog! dlg.Destroy() - + def OnFloatSpin(self, event): floatspin = event.GetEventObject() self.log.write("FloatSpin event: Value = %s\n"%floatspin.GetValue()) - + indx = self.floatspins.index(floatspin) fmt = floatspin.GetFormat() @@ -451,10 +451,10 @@ class FloatSpinDemo(wx.Panel): currenttext = self.textvalues[indx] strs = ("%100." + str(dgt) + fmt[1])%floatspin.GetValue() - + currenttext.SetValue(strs.strip()) currenttext.Refresh() - + #---------------------------------------------------------------------- diff --git a/demo/agw/FoldPanelBar.py b/demo/agw/FoldPanelBar.py index 28377965..fd91ffbf 100644 --- a/demo/agw/FoldPanelBar.py +++ b/demo/agw/FoldPanelBar.py @@ -1,5 +1,5 @@ import wx - +import wx.adv import os import sys @@ -51,12 +51,12 @@ zzW\xcff&\xb8,\x89\xa8@Q\xd6\xaaf\xdfRm,\xee\xb1BDxr#\xae\xf5|\xddo\xd6\xe2H\ \x00\x00\x00IEND\xaeB`\x82' def GetCollapsedIconBitmap(): - return wx.BitmapFromImage(GetCollapsedIconImage()) + return wx.Bitmap(GetCollapsedIconImage()) def GetCollapsedIconImage(): import cStringIO stream = cStringIO.StringIO(GetCollapsedIconData()) - return wx.ImageFromStream(stream) + return wx.Image(stream) #---------------------------------------------------------------------- def GetExpandedIconData(): @@ -83,12 +83,12 @@ def GetExpandedIconData(): `\x82' def GetExpandedIconBitmap(): - return wx.BitmapFromImage(GetExpandedIconImage()) + return wx.Bitmap(GetExpandedIconImage()) def GetExpandedIconImage(): import cStringIO stream = cStringIO.StringIO(GetExpandedIconData()) - return wx.ImageFromStream(stream) + return wx.Image(stream) #---------------------------------------------------------------------- def GetMondrianData(): @@ -102,15 +102,15 @@ o\xda\x84pB2\x1f\x81Fa\x8c\x9c\x08\x04Z{\xcf\xa72\xbcv\xfa\xc5\x08 \x80r\x80\ \x04\x10@\xf9X\xbe\x00\xc9 \x14K\xc1<={\x00\x00\x00\x00IEND\xaeB`\x82' def GetMondrianBitmap(): - return wx.BitmapFromImage(GetMondrianImage()) + return wx.Bitmap(GetMondrianImage()) def GetMondrianImage(): import cStringIO stream = cStringIO.StringIO(GetMondrianData()) - return wx.ImageFromStream(stream) + return wx.Image(stream) def GetMondrianIcon(): - icon = wx.EmptyIcon() + icon = wx.Icon() icon.CopyFromBitmap(GetMondrianBitmap()) return icon @@ -130,19 +130,19 @@ class Extended(wx.Frame): self.SetIcon(GetMondrianIcon()) self.SetMenuBar(self.CreateMenuBar()) - self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-4, -3]) self.statusbar.SetStatusText("Andrea Gavana @ 23 Mar 2005", 0) self.statusbar.SetStatusText("Welcome to wxPython!", 1) - self._leftWindow1 = wx.SashLayoutWindow(self, 101, wx.DefaultPosition, + self._leftWindow1 = wx.adv.SashLayoutWindow(self, 101, wx.DefaultPosition, wx.Size(200, 1000), wx.NO_BORDER | - wx.SW_3D | wx.CLIP_CHILDREN) + wx.adv.SW_3D | wx.CLIP_CHILDREN) self._leftWindow1.SetDefaultSize(wx.Size(220, 1000)) - self._leftWindow1.SetOrientation(wx.LAYOUT_VERTICAL) - self._leftWindow1.SetAlignment(wx.LAYOUT_LEFT) - self._leftWindow1.SetSashVisible(wx.SASH_RIGHT, True) + self._leftWindow1.SetOrientation(wx.adv.LAYOUT_VERTICAL) + self._leftWindow1.SetAlignment(wx.adv.LAYOUT_LEFT) + self._leftWindow1.SetSashVisible(wx.adv.SASH_RIGHT, True) self._leftWindow1.SetExtraBorderSize(10) self._pnl = 0 @@ -158,7 +158,7 @@ class Extended(wx.Frame): self.ID_WINDOW_RIGHT1 = 102 self.ID_WINDOW_BOTTOM = 103 - self._leftWindow1.Bind(wx.EVT_SASH_DRAGGED_RANGE, self.OnFoldPanelBarDrag, + self._leftWindow1.Bind(wx.adv.EVT_SASH_DRAGGED_RANGE, self.OnFoldPanelBarDrag, id=100, id2=103) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_SCROLL, self.OnSlideColour) @@ -168,7 +168,7 @@ class Extended(wx.Frame): def OnSize(self, event): - wx.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace) + wx.adv.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace) event.Skip() @@ -646,7 +646,7 @@ class Collapsed(wx.Frame): self.SetIcon(GetMondrianIcon()) self.SetMenuBar(self.CreateMenuBar()) - self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-4, -3]) self.statusbar.SetStatusText("Andrea Gavana @ 23 Mar 2005", 0) self.statusbar.SetStatusText("Welcome to wxPython!", 1) @@ -715,7 +715,7 @@ class Collapsed(wx.Frame): self.pnl = bar size = self.GetClientSize() - self.pnl.SetDimensions(0, 0, size.GetWidth(), size.GetHeight()) + self.pnl.SetSize(0, 0, size.GetWidth(), size.GetHeight()) def CreateMenuBar(self): @@ -793,7 +793,7 @@ class NotCollapsed(wx.Frame): self.SetIcon(GetMondrianIcon()) self.SetMenuBar(self.CreateMenuBar()) - self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-4, -3]) self.statusbar.SetStatusText("Andrea Gavana @ 23 Mar 2005", 0) self.statusbar.SetStatusText("Welcome to wxPython!", 1) diff --git a/demo/agw/FourWaySplitter.py b/demo/agw/FourWaySplitter.py index b80d1696..bfa1206d 100644 --- a/demo/agw/FourWaySplitter.py +++ b/demo/agw/FourWaySplitter.py @@ -53,7 +53,7 @@ class ControlPane(wx.Panel): style=wx.CB_READONLY|wx.CB_DROPDOWN) combo.SetStringSelection("None") - self.Bind(wx.EVT_COMBOBOX, self.OnExpandWindow) + self.Bind(wx.EVT_COMBOBOX, self.OnExpandWindow) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(luCheck, 0, wx.TOP, 5) @@ -148,7 +148,7 @@ class FWSPanel(wx.Panel): def OnChanging(self, event): - idx = self.GetSashIdx(event) + idx = self.GetSashIdx(event) self.log.write("Changing sash: %s %s\n" %(idx, event.GetSashPosition())) # This is one way to control the sash limits @@ -160,7 +160,7 @@ class FWSPanel(wx.Panel): def OnChanged(self, event): - idx = self.GetSashIdx(event) + idx = self.GetSashIdx(event) self.log.write("Changed sash: %s %s\n" %(idx, event.GetSashPosition())) event.Skip() @@ -185,7 +185,7 @@ class FWSPanel(wx.Panel): win1 = self.splitter.GetWindow(0) win3 = self.splitter.GetWindow(2) - self.splitter.ExchangeWindows(win1, win3) + self.splitter.ExchangeWindows(win1, win3) def ExpandWindow(self, selection): @@ -203,12 +203,12 @@ class FourWaySplitterDemo(wx.Frame): self.log = log panel = FWSPanel(self, log) - sizer = wx.BoxSizer(wx.VERTICAL) + sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(panel, 1, wx.EXPAND) self.SetSizer(sizer) sizer.Layout() - statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + statusbar = self.CreateStatusBar(2) statusbar.SetStatusWidths([-2, -1]) # statusbar fields statusbar_fields = [("FourWaySplitter wxPython Demo, Andrea Gavana @ 03 Nov 2006"), @@ -219,7 +219,7 @@ class FourWaySplitterDemo(wx.Frame): self.CreateMenu() - self.SetIcon(images.Mondrian.GetIcon()) + self.SetIcon(images.Mondrian.GetIcon()) self.CenterOnScreen() @@ -231,11 +231,11 @@ class FourWaySplitterDemo(wx.Frame): item = wx.MenuItem(fileMenu, wx.ID_ANY, "E&xit") self.Bind(wx.EVT_MENU, self.OnQuit, item) - fileMenu.AppendItem(item) + fileMenu.Append(item) item = wx.MenuItem(helpMenu, wx.ID_ANY, "About") self.Bind(wx.EVT_MENU, self.OnAbout, item) - helpMenu.AppendItem(item) + helpMenu.Append(item) menuBar.Append(fileMenu, "&File") menuBar.Append(helpMenu, "&Help") diff --git a/demo/agw/GradientButton.py b/demo/agw/GradientButton.py index 2d65df01..fbbed219 100644 --- a/demo/agw/GradientButton.py +++ b/demo/agw/GradientButton.py @@ -33,19 +33,19 @@ class GradientButtonDemo(wx.Panel): bitmap = wx.Bitmap(os.path.normpath(bitmapDir+"gradientbutton.png"), wx.BITMAP_TYPE_PNG) self.btn2 = GB.GradientButton(self.mainPanel, -1, bitmap, "GradientButton") - self.topStartColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetTopStartColour(), + self.topStartColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetTopStartColour(), name="Top Start") - self.topEndColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetTopEndColour(), + self.topEndColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetTopEndColour(), name="Top End") - self.bottomStartColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetBottomStartColour(), + self.bottomStartColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetBottomStartColour(), name="Bottom Start") - self.bottomEndColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetBottomEndColour(), + self.bottomEndColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetBottomEndColour(), name="Bottom End") - self.pressedTopColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetPressedTopColour(), + self.pressedTopColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetPressedTopColour(), name="Pressed Top") - self.pressedBottomColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetPressedBottomColour(), + self.pressedBottomColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetPressedBottomColour(), name="Pressed Bottom") - self.textColour = wx.ColourPickerCtrl(self.mainPanel, col=self.btn2.GetForegroundColour(), + self.textColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.btn2.GetForegroundColour(), name="Text Colour") self.DoLayout() @@ -85,14 +85,14 @@ class GradientButtonDemo(wx.Panel): btnSizer.Add((10, 0)) mainSizer.Add(btnSizer, 0, wx.EXPAND|wx.ALL, 10) - boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + boldFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) boldFont.SetWeight(wx.BOLD) for child in self.mainPanel.GetChildren(): if isinstance(child, wx.StaticText): child.SetFont(boldFont) - buttonFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + buttonFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) buttonFont.SetWeight(wx.BOLD) try: buttonFont.SetFaceName("Tahoma") diff --git a/demo/agw/LabelBook.py b/demo/agw/LabelBook.py index 3148576d..ae148766 100644 --- a/demo/agw/LabelBook.py +++ b/demo/agw/LabelBook.py @@ -127,7 +127,7 @@ class LabelBookDemo(wx.Frame): self.Bind(LB.EVT_IMAGENOTEBOOK_PAGE_CLOSED, self.OnPageClosed) - statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + statusbar = self.CreateStatusBar(2) statusbar.SetStatusWidths([-2, -1]) # statusbar fields statusbar_fields = [("LabelBook & FlatImageBook wxPython Demo, Andrea Gavana @ 03 Nov 2006"), @@ -483,25 +483,25 @@ class LabelBookDemo(wx.Frame): item = wx.MenuItem(fileMenu, wx.ID_ANY, "E&xit") self.Bind(wx.EVT_MENU, self.OnQuit, item) - fileMenu.AppendItem(item) + fileMenu.Append(item) item = wx.MenuItem(editMenu, wx.ID_ANY, "Add Page") self.Bind(wx.EVT_MENU, self.OnAddPage, item) - editMenu.AppendItem(item) + editMenu.Append(item) editMenu.AppendSeparator() item = wx.MenuItem(editMenu, wx.ID_ANY, "Delete Page") self.Bind(wx.EVT_MENU, self.OnDeletePage, item) - editMenu.AppendItem(item) + editMenu.Append(item) item = wx.MenuItem(editMenu, wx.ID_ANY, "Delete All Pages") self.Bind(wx.EVT_MENU, self.OnDeleteAllPages, item) - editMenu.AppendItem(item) + editMenu.Append(item) item = wx.MenuItem(helpMenu, wx.ID_ANY, "About") self.Bind(wx.EVT_MENU, self.OnAbout, item) - helpMenu.AppendItem(item) + helpMenu.Append(item) menuBar.Append(fileMenu, "&File") menuBar.Append(editMenu, "&Edit") diff --git a/demo/agw/MacLargeDemo.py b/demo/agw/MacLargeDemo.py index 5903a21a..1a3a4d56 100644 --- a/demo/agw/MacLargeDemo.py +++ b/demo/agw/MacLargeDemo.py @@ -110,27 +110,27 @@ class MacRenderer(object): DONE_BITMAP = None REMAINING_BITMAP = None - + def __init__(self, parent): self.progressValue = random.randint(1, 99) - + def DrawSubItem(self, dc, rect, line, highlighted, enabled): """Draw a custom progress bar using double buffering to prevent flicker""" - canvas = wx.EmptyBitmap(rect.width, rect.height) + canvas = wx.Bitmap(rect.width, rect.height) mdc = wx.MemoryDC() mdc.SelectObject(canvas) if highlighted: - mdc.SetBackground(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))) + mdc.SetBackground(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT))) mdc.SetTextForeground(wx.WHITE) else: - mdc.SetBackground(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))) + mdc.SetBackground(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))) mdc.Clear() - mdc.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False)) + mdc.SetFont(wx.Font(9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False)) if line == 0: text1 = "Apple Ads" @@ -147,7 +147,7 @@ class MacRenderer(object): xtext, ytext = mdc.GetTextExtent(text1) mdc.DrawText(text1, 0, ypos) ypos += ytext + 5 - + mdc.SetFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL, False)) xtext, ytext = mdc.GetTextExtent(text2) @@ -155,35 +155,35 @@ class MacRenderer(object): ypos += ytext + 5 self.DrawProgressBar(mdc, 0, ypos, rect.width, 20, progress) - + mdc.SetFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL, False)) ypos += 25 mdc.DrawText(text3, 0, ypos) dc.Blit(rect.x+3, rect.y, rect.width-6, rect.height, mdc, 0, 0) - + def GetLineHeight(self): dc = wx.MemoryDC() - dc.SelectObject(wx.EmptyBitmap(1, 1)) - dc.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD, False)) + dc.SelectObject(wx.Bitmap(1, 1)) + dc.SetFont(wx.Font(9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False)) dummy, ytext1 = dc.GetTextExtent("Agw") - dc.SetFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL, False)) + dc.SetFont(wx.Font(7, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False)) dummy, ytext2 = dc.GetTextExtent("Agw") dc.SelectObject(wx.NullBitmap) return ytext1 + 2*ytext2 + 40 - + def GetSubItemWidth(self): return 250 - + def DrawHorizontalPipe(self, dc, x, y, w, colour): """Draws a horizontal 3D-looking pipe.""" - + for r in range(PIPE_HEIGHT): red = int(colour.Red() * math.sin((math.pi/PIPE_HEIGHT)*r)) green = int(colour.Green() * math.sin((math.pi/PIPE_HEIGHT)*r)) @@ -194,26 +194,26 @@ class MacRenderer(object): def DrawProgressBar(self, dc, x, y, w, h, percent): """ - Draws a progress bar in the (x,y,w,h) box that represents a progress of - 'percent'. The progress bar is only horizontal and it's height is constant - (PIPE_HEIGHT). The 'h' parameter is used to vertically center the progress + Draws a progress bar in the (x,y,w,h) box that represents a progress of + 'percent'. The progress bar is only horizontal and it's height is constant + (PIPE_HEIGHT). The 'h' parameter is used to vertically center the progress bar in the allotted space. - + The drawing is speed-optimized. Two bitmaps are created the first time this function runs - one for the done (green) part of the progress bar and one for the remaining (white) part. During normal operation the function just cuts the necessary part of the two bitmaps and draws them. """ - + # Create two pipes if self.DONE_BITMAP is None: - self.DONE_BITMAP = wx.EmptyBitmap(PIPE_WIDTH, PIPE_HEIGHT) + self.DONE_BITMAP = wx.Bitmap(PIPE_WIDTH, PIPE_HEIGHT) mdc = wx.MemoryDC() mdc.SelectObject(self.DONE_BITMAP) self.DrawHorizontalPipe(mdc, 0, 0, PIPE_WIDTH, wx.GREEN) mdc.SelectObject(wx.NullBitmap) - self.REMAINING_BITMAP = wx.EmptyBitmap(PIPE_WIDTH, PIPE_HEIGHT) + self.REMAINING_BITMAP = wx.Bitmap(PIPE_WIDTH, PIPE_HEIGHT) mdc = wx.MemoryDC() mdc.SelectObject(self.REMAINING_BITMAP) self.DrawHorizontalPipe(mdc, 0, 0, PIPE_WIDTH, wx.RED) @@ -221,7 +221,7 @@ class MacRenderer(object): mdc.SelectObject(wx.NullBitmap) # Center the progress bar vertically in the box supplied - y = y + (h - PIPE_HEIGHT)/2 + y = y + (h - PIPE_HEIGHT)/2 if percent == 0: middle = 0 @@ -230,7 +230,7 @@ class MacRenderer(object): if w < 1: return - + if middle == 0: # not started bitmap = self.REMAINING_BITMAP.GetSubBitmap((1, 0, w, PIPE_HEIGHT)) dc.DrawBitmap(bitmap, x, y, False) @@ -242,30 +242,30 @@ class MacRenderer(object): dc.DrawBitmap(doneBitmap, x, y, False) remainingBitmap = self.REMAINING_BITMAP.GetSubBitmap((0, 0, w - middle, PIPE_HEIGHT)) dc.DrawBitmap(remainingBitmap, x + middle, y, False) - + class TestUltimateListCtrl(ULC.UltimateListCtrl, listmix.ListCtrlAutoWidthMixin): - + def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, agwStyle=0): - + ULC.UltimateListCtrl.__init__(self, parent, id, pos, size, style, agwStyle) listmix.ListCtrlAutoWidthMixin.__init__(self) - - + + class UltimateListCtrlPanel(wx.Panel): - + def __init__(self, parent, log): wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS) sizer = wx.BoxSizer(wx.VERTICAL) - self.log = log + self.log = log self.il = wx.ImageList(32, 32) self.il.Add(folder.GetBitmap()) self.il.Add(movie.GetBitmap()) - + self.list = TestUltimateListCtrl(self, -1, agwStyle=wx.LC_REPORT | wx.BORDER_SUNKEN @@ -276,7 +276,7 @@ class UltimateListCtrlPanel(wx.Panel): | wx.LC_HRULES #| wx.LC_SINGLE_SEL | ULC.ULC_HAS_VARIABLE_ROW_HEIGHT) - + self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL) sizer.Add(self.list, 1, wx.EXPAND) @@ -285,25 +285,25 @@ class UltimateListCtrlPanel(wx.Panel): self.SetAutoLayout(True) self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.OnColBeginDrag, self.list) - + def PopulateList(self): self.list.Freeze() info = ULC.UltimateListItem() - info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT - info._format = 0 - info._text = "" - + info.Mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT + info.Align = 0 + info.Text = "" + self.list.InsertColumnInfo(0, info) info = ULC.UltimateListItem() - info._format = wx.LIST_FORMAT_LEFT - info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT - info._image = [] - info._text = "Some useful info here" - + info.Align = wx.LIST_FORMAT_LEFT + info.Mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT + info.Image = [] + info.Text = "Some useful info here" + self.list.InsertColumnInfo(1, info) for i in xrange(2): @@ -325,7 +325,7 @@ class UltimateListCtrlPanel(wx.Panel): return event.Skip() - + #--------------------------------------------------------------------------- @@ -338,11 +338,11 @@ class TestFrame(wx.Frame): self.log = log # Create the CustomTreeCtrl, using a derived class defined below self.ulc = UltimateListCtrlPanel(self, self.log) - + self.SetIcon(images.Mondrian.GetIcon()) self.CenterOnScreen() self.Show() - + #--------------------------------------------------------------------------- if __name__ == '__main__': diff --git a/demo/agw/PeakMeter.py b/demo/agw/PeakMeter.py index 8a974d5b..0f1ec951 100644 --- a/demo/agw/PeakMeter.py +++ b/demo/agw/PeakMeter.py @@ -25,7 +25,7 @@ class PeakMeterCtrlDemo(wx.Panel): self.log = log self.mainPanel = wx.Panel(self) - + # Initialize Peak Meter control 1 self.vertPeak = PM.PeakMeterCtrl(self.mainPanel, -1, style=wx.SIMPLE_BORDER, agwStyle=PM.PM_VERTICAL) # Initialize Peak Meter control 2 @@ -39,19 +39,19 @@ class PeakMeterCtrlDemo(wx.Panel): self.falloffCheck = wx.CheckBox(self.mainPanel, -1, "Show Falloff Effect") colour = self.mainPanel.GetBackgroundColour() - self.backColour = wx.ColourPickerCtrl(self.mainPanel, col=colour) - self.lowColour = wx.ColourPickerCtrl(self.mainPanel, col=wx.GREEN) - self.mediumColour = wx.ColourPickerCtrl(self.mainPanel, col=wx.NamedColour("yellow")) - self.highColour = wx.ColourPickerCtrl(self.mainPanel, col=wx.RED) - + self.backColour = wx.ColourPickerCtrl(self.mainPanel, colour=colour) + self.lowColour = wx.ColourPickerCtrl(self.mainPanel, colour=wx.GREEN) + self.mediumColour = wx.ColourPickerCtrl(self.mainPanel, colour=wx.YELLOW) + self.highColour = wx.ColourPickerCtrl(self.mainPanel, colour=wx.RED) + self.timer = wx.Timer(self) self.SetProperties() self.DoLayout() self.BindEvents() - - def SetProperties(self): + + def SetProperties(self): self.vertPeak.SetMeterBands(10, 15) self.horzPeak.SetMeterBands(10, 15) @@ -78,7 +78,7 @@ class PeakMeterCtrlDemo(wx.Panel): mainSizer.Add(horzSizer, 0, wx.EXPAND) mainSizer.Add(self.staticLine, 0, wx.EXPAND|wx.ALL, 5) - + checkSizer.Add(self.gridCheck, 0, wx.EXPAND|wx.ALL, 5) checkSizer.Add(self.falloffCheck, 0, wx.EXPAND|wx.LEFT|wx.BOTTOM, 5) @@ -102,7 +102,7 @@ class PeakMeterCtrlDemo(wx.Panel): bottomSizer.Add(colourSizer, 0, wx.EXPAND|wx.ALL, 5) bottomSizer.Add((0, 5)) mainSizer.Add(bottomSizer, 0, wx.EXPAND|wx.BOTTOM|wx.RIGHT, 5) - + self.mainPanel.SetSizer(mainSizer) mainSizer.Layout() frameSizer.Add(self.mainPanel, 1, wx.EXPAND) @@ -126,7 +126,7 @@ class PeakMeterCtrlDemo(wx.Panel): # generate 15 random number and set them as data for the meter nElements = 15 arrayData = [] - + for i in xrange(nElements): nRandom = random.randint(0, 100) arrayData.append(nRandom) @@ -158,7 +158,7 @@ class PeakMeterCtrlDemo(wx.Panel): self.timer.Stop() self.vertPeak.Stop() self.horzPeak.Stop() - + def OnPickColour(self, event): @@ -172,7 +172,7 @@ class PeakMeterCtrlDemo(wx.Panel): high = self.highColour.GetColour() self.horzPeak.SetBandsColour(low, med, high) - + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/agw/PersistentControls.py b/demo/agw/PersistentControls.py index 1387732d..e03cc89d 100644 --- a/demo/agw/PersistentControls.py +++ b/demo/agw/PersistentControls.py @@ -35,7 +35,7 @@ _sampleText2 = "wx.Frame, wx.SplitterWindow, wx.TreeCtrl, wx.Notebook, " \ _sampleList = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'] _sampleList2 = _sampleList + ['nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen'] - + _title = "PersistentControls for wxPython :-D " _configFile1 = os.path.join(dirName, "Example1") _configFile2 = os.path.join(dirName, "Example2") @@ -52,7 +52,7 @@ class PersistentPanel(wx.Panel): mainSizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.FlexGridSizer(3, 2, 10, 10) - + btn1 = wx.Button(self, -1, "Example 1") text1 = ExpandoTextCtrl(self, -1, _sampleText1, size=(300,-1), style=wx.TE_READONLY) @@ -61,7 +61,7 @@ class PersistentPanel(wx.Panel): sizer.Add(btn1, 0, wx.ALIGN_CENTER) sizer.Add(text1, 1, wx.EXPAND) - + sizer.Add(btn2, 0, wx.ALIGN_CENTER) sizer.Add(text2, 1, wx.EXPAND) @@ -69,7 +69,7 @@ class PersistentPanel(wx.Panel): mainSizer.Add(sizer, 1, wx.EXPAND|wx.ALL, 20) self.SetSizer(mainSizer) mainSizer.Layout() - + btn1.Bind(wx.EVT_BUTTON, self.OnExample1) btn2.Bind(wx.EVT_BUTTON, self.OnExample2) @@ -82,14 +82,14 @@ class PersistentPanel(wx.Panel): def OnExample2(self, event): frame = PersistentFrame2(self, _title + "- Example 2", (700, 500)) - + class PersistentFrame1(wx.Frame): def __init__(self, parent, title, size): wx.Frame.__init__(self, parent, -1, title, size=size, name="Example1") - + self._auiMgr = AUI.AuiManager() self._auiMgr.SetManagedWindow(self) @@ -105,10 +105,10 @@ class PersistentFrame1(wx.Frame): self.CenterOnParent() self.Show() - self.Bind(wx.EVT_CLOSE, self.OnClose) + self.Bind(wx.EVT_CLOSE, self.OnClose) wx.CallAfter(self.RegisterControls) - - + + def CreateMenuBar(self): # Prepare the menu bar @@ -121,7 +121,7 @@ class PersistentFrame1(wx.Frame): menu1.Append(102, "wx.F&ontDialog") menu1.AppendSeparator() menu1.Append(103, "wx.&TextEntryDialog") - menu1.AppendSeparator() + menu1.AppendSeparator() menu1.Append(105, "&Close", "Close this frame") # Add menu to the menu bar menuBar.Append(menu1, "&Dialogs") @@ -154,7 +154,7 @@ class PersistentFrame1(wx.Frame): tb3 = AUI.AuiToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize, AUI.AUI_TB_DEFAULT_STYLE) tb3.SetName("AuiToolBar") tb3.SetToolBitmapSize(wx.Size(16, 16)) - + tb3_bmp1 = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, wx.Size(16, 16)) tb3.AddSimpleTool(ID_AuiToolBar, "Check 1", tb3_bmp1, "Check 1", AUI.ITEM_CHECK) tb3.AddSimpleTool(ID_AuiToolBar+1, "Check 2", tb3_bmp1, "Check 2", AUI.ITEM_CHECK) @@ -203,7 +203,7 @@ class PersistentFrame1(wx.Frame): box1.Add(fgs, 1, wx.EXPAND|wx.ALL, 5) pickerPanel.SetSizer(box1) box1.Layout() - + otherPanel = wx.Panel(self) box2 = wx.BoxSizer(wx.VERTICAL) @@ -214,7 +214,7 @@ class PersistentFrame1(wx.Frame): name="ComboBox1") boldFont = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "") - + box2 = wx.BoxSizer(wx.HORIZONTAL) box2.Add((0, 0), 1) box2.Add(radiobox, 0, wx.ALL|wx.ALIGN_CENTER, 5) @@ -232,11 +232,11 @@ class PersistentFrame1(wx.Frame): box2.Add(sizer_1, 1, wx.EXPAND|wx.ALIGN_CENTER, 0) box2.Add((0, 0), 1, 1) - otherPanel.SetSizer(box2) + otherPanel.SetSizer(box2) otherPanel2 = wx.Panel(self) box3 = wx.BoxSizer(wx.VERTICAL) - + gs1 = wx.FlexGridSizer(2, 3, 5, 10) slider = wx.Slider(otherPanel2, -1, 3, 0, 10, style=wx.SL_HORIZONTAL|wx.SL_LABELS, @@ -280,14 +280,14 @@ class PersistentFrame1(wx.Frame): def Register(self, children=None): - + if children is None: self._persistMgr.RegisterAndRestore(self) self._persistMgr.RegisterAndRestore(self.GetMenuBar()) children = self.GetChildren() - + for child in children: - + name = child.GetName() if name not in PM.BAD_DEFAULT_NAMES and "widget" not in name and \ @@ -297,7 +297,7 @@ class PersistentFrame1(wx.Frame): if child.GetChildren(): self.Register(child.GetChildren()) - + def CloseWindow(self, event): @@ -308,7 +308,7 @@ class PersistentFrame1(wx.Frame): self._persistMgr.SaveAndUnregister() event.Skip() - + def OnDialogs(self, event): @@ -319,7 +319,7 @@ class PersistentFrame1(wx.Frame): data = wx.ColourData() dlg = wx.ColourDialog(self, data) dlg.SetName("ColourDialog1") - + elif evId == 102: # wx.FontDialog data = wx.FontData() @@ -340,7 +340,7 @@ class PersistentFrame1(wx.Frame): self._persistMgr.Unregister(dlg) dlg.Destroy() - + # The wx.HtmlListBox derives from wx.VListBox, but draws each item # itself as a wx.HtmlCell. @@ -354,7 +354,7 @@ class MyHtmlListBox(wx.HtmlListBox): class PersistentFrame2(wx.Frame): - + def __init__(self, parent, title, size): wx.Frame.__init__(self, parent, -1, title, size=size, name="Example2") @@ -365,11 +365,11 @@ class PersistentFrame2(wx.Frame): self.split1 = wx.SplitterWindow(self, -1, style=wx.SP_3D|wx.SP_BORDER, name="Splitter1") self.treectrl = self.CreateTreeListCtrl(False) - + self.split2 = wx.SplitterWindow(self.split1, -1, style=wx.SP_3D|wx.SP_BORDER, name="Splitter2") self.notebook = wx.Notebook(self.split2, name="Notebook1") dummyPanel = wx.Panel(self.split2) - + text = "Hello world!\nI am a simple wx.TextCtrl" \ "I will remember my value if you change it!" @@ -385,14 +385,14 @@ class PersistentFrame2(wx.Frame): self.DoLayout(dummyPanel) self.SetIcon(images.Mondrian.Icon) - - self.Bind(wx.EVT_CLOSE, self.OnClose) + + self.Bind(wx.EVT_CLOSE, self.OnClose) wx.CallAfter(self.RegisterControls) self.CenterOnParent() self.Show() - + def DoLayout(self, dummyPanel): sizer_5 = wx.BoxSizer(wx.HORIZONTAL) @@ -441,7 +441,7 @@ class PersistentFrame2(wx.Frame): il = wx.ImageList(16, 16) il.Add(images.Smiles.GetBitmap()) - + listCtrl = wx.ListCtrl(self.notebook, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER, name="ListCtrl1") for col in xrange(6): listCtrl.InsertColumn(col, "Column %d"%col) @@ -453,7 +453,7 @@ class PersistentFrame2(wx.Frame): idx = listCtrl.InsertImageStringItem(sys.maxint, text%(row+1, 1), 0) else: idx = listCtrl.InsertStringItem(sys.maxint, text%(row+1, 1)) - + for col in xrange(1, 6): listCtrl.SetStringItem(idx, col, text%(row+1, col+1), random.randint(0, 1)-1) @@ -525,9 +525,9 @@ class PersistentFrame2(wx.Frame): hlb.SetItemCount(300) hlb.SetSelection(0) - return hlb + return hlb + - def OnClose(self, event): self._persistMgr.SaveAndUnregister() @@ -546,11 +546,11 @@ class PersistentFrame2(wx.Frame): if children is None: self._persistMgr.RegisterAndRestore(self) children = self.GetChildren() - + for child in children: - + name = child.GetName() - + if name not in PM.BAD_DEFAULT_NAMES and "wxtreelist" not in name and \ "AuiTabCtrl" not in name: self._persistMgr.RegisterAndRestore(child) @@ -558,7 +558,7 @@ class PersistentFrame2(wx.Frame): if child.GetChildren(): self.Register(child.GetChildren()) - + #---------------------------------------------------------------------- def runTest(frame, nb, log): @@ -570,7 +570,7 @@ def runTest(frame, nb, log): overview = PM.__doc__ -if __name__ == '__main__': +if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) diff --git a/demo/agw/PieCtrl.py b/demo/agw/PieCtrl.py index e242c97c..bc1f161d 100644 --- a/demo/agw/PieCtrl.py +++ b/demo/agw/PieCtrl.py @@ -62,7 +62,7 @@ class PieCtrlDemo(wx.Panel): self._incr = 1 self._hiddenlegend = False - panel.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNFACE)) + panel.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE)) # Create A Simple PieCtrl With 3 Sectors self._pie = PieCtrl(panel, -1, wx.DefaultPosition, wx.Size(180,270)) diff --git a/demo/agw/PyGauge.py b/demo/agw/PyGauge.py index a98833a1..81d790d9 100644 --- a/demo/agw/PyGauge.py +++ b/demo/agw/PyGauge.py @@ -17,7 +17,7 @@ except ImportError: # if it's not there locally, try the wxPython lib. except: raise Exception("This demo requires wxPython version greater than 2.9.0.0") - + class PyGaugeDemo(wx.Panel): def __init__(self, parent, log): @@ -27,53 +27,51 @@ class PyGaugeDemo(wx.Panel): self.mainPanel = wx.Panel(self) self.mainPanel.SetBackgroundColour(wx.WHITE) - + self.gauge1 = PG.PyGauge(self.mainPanel, -1, size=(100,25),style=wx.GA_HORIZONTAL) self.gauge1.SetValue(80) self.gauge1.SetBackgroundColour(wx.WHITE) self.gauge1.SetBorderColor(wx.BLACK) - + self.gauge2 = PG.PyGauge(self.mainPanel, -1, size=(100,25),style=wx.GA_HORIZONTAL) self.gauge2.SetValue([20,80]) self.gauge2.SetBarColor([wx.Colour(162,255,178),wx.Colour(159,176,255)]) self.gauge2.SetBackgroundColour(wx.WHITE) self.gauge2.SetBorderColor(wx.BLACK) self.gauge2.SetBorderPadding(2) - self.gauge2.SetDrawValue(draw=True, drawPercent=True, font=wx.SMALL_FONT, colour=wx.BLUE) - self.gauge2.Update([30,0],2000) - + self.gauge3 = PG.PyGauge(self.mainPanel, -1, size=(100,25),style=wx.GA_HORIZONTAL) self.gauge3.SetValue(50) self.gauge3.SetBarColor(wx.GREEN) self.gauge3.SetBackgroundColour(wx.WHITE) self.gauge3.SetBorderColor(wx.BLACK) - self.backColour = wx.ColourPickerCtrl(self.mainPanel, col=self.gauge3.GetBackgroundColour()) - self.borderColour = wx.ColourPickerCtrl(self.mainPanel, col=self.gauge3.GetBorderColour()) - self.barColour = wx.ColourPickerCtrl(self.mainPanel, col=self.gauge3.GetBarColour()) + self.backColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.gauge3.GetBackgroundColour()) + self.borderColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.gauge3.GetBorderColour()) + self.barColour = wx.ColourPickerCtrl(self.mainPanel, colour=self.gauge3.GetBarColour()) self.gaugeValue = wx.TextCtrl(self.mainPanel, -1, str(self.gauge3.GetValue()), style=wx.TE_PROCESS_ENTER) self.gaugeRange = wx.TextCtrl(self.mainPanel, -1, str(self.gauge3.GetRange()), style=wx.TE_PROCESS_ENTER) self.gaugePadding = wx.TextCtrl(self.mainPanel, -1, str(self.gauge3.GetBorderPadding()), style=wx.TE_PROCESS_ENTER) self.DoLayout() self.BindEvents() - + def DoLayout(self): frameSizer = wx.BoxSizer(wx.VERTICAL) - mainSizer = wx.BoxSizer(wx.VERTICAL) + mainSizer = wx.BoxSizer(wx.VERTICAL) colourSizer = wx.FlexGridSizer(2, 6, 1, 10) - + label1 = wx.StaticText(self.mainPanel, -1, "Welcome to the PyGauge demo for wxPython!") mainSizer.Add(label1, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 10) mainSizer.Add(self.gauge1, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 20) mainSizer.Add(self.gauge2, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 20) mainSizer.Add(self.gauge3, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 20) - + labelBack = wx.StaticText(self.mainPanel, -1, "Background Colour") labelHover = wx.StaticText(self.mainPanel, -1, "Border Colour") labelText = wx.StaticText(self.mainPanel, -1, "Bar Colour") @@ -96,15 +94,15 @@ class PyGaugeDemo(wx.Panel): colourSizer.Add(self.gaugePadding, 0, wx.EXPAND) mainSizer.Add(colourSizer, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10) - - boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + + boldFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) boldFont.SetWeight(wx.BOLD) - + for child in self.mainPanel.GetChildren(): if isinstance(child, wx.StaticText): child.SetFont(boldFont) - + self.mainPanel.SetSizer(mainSizer) mainSizer.Layout() frameSizer.Add(self.mainPanel, 1, wx.EXPAND) @@ -118,7 +116,7 @@ class PyGaugeDemo(wx.Panel): self.Bind(wx.EVT_TEXT_ENTER, self.OnEnter, self.gaugeValue) self.Bind(wx.EVT_TEXT_ENTER, self.OnEnter, self.gaugeRange) self.Bind(wx.EVT_TEXT_ENTER, self.OnEnter, self.gaugePadding) - + def OnEnter(self,event): obj = event.GetEventObject() if obj == self.gaugeValue: @@ -128,7 +126,7 @@ class PyGaugeDemo(wx.Panel): if obj == self.gaugePadding: self.gauge3.SetBorderPadding(int(self.gaugePadding.GetValue())) self.gauge3.Refresh() - + def OnPickColour(self, event): @@ -140,10 +138,10 @@ class PyGaugeDemo(wx.Panel): self.gauge3.SetBorderColour(colour) else: self.gauge3.SetBarColour(colour) - + self.gauge3.Refresh() - + #---------------------------------------------------------------------- def runTest(frame, nb, log): diff --git a/demo/agw/PyProgress.py b/demo/agw/PyProgress.py index 1a87b5fb..93bcf036 100644 --- a/demo/agw/PyProgress.py +++ b/demo/agw/PyProgress.py @@ -45,13 +45,13 @@ class PyProgressDemo(wx.Panel): static1 = wx.StaticText(self.panel, -1, "Gauge Proportion (%): ") self.slider1 = wx.Slider(self.panel, -1, 20, 1, 99, style=wx.SL_HORIZONTAL| wx.SL_AUTOTICKS|wx.SL_LABELS) - self.slider1.SetTickFreq(10, 1) + self.slider1.SetTickFreq(10) self.slider1.SetValue(20) static2 = wx.StaticText(self.panel, -1, "Gauge Steps: ") self.slider2 = wx.Slider(self.panel, -1, 50, 2, 100, style=wx.SL_HORIZONTAL| wx.SL_AUTOTICKS|wx.SL_LABELS) - self.slider2.SetTickFreq(10, 1) + self.slider2.SetTickFreq(10) self.slider2.SetValue(50) static3 = wx.StaticText(self.panel, -1, "Gauge Background Colour: ") diff --git a/demo/agw/RibbonBar.py b/demo/agw/RibbonBar.py index 4135a6db..75c29a9d 100644 --- a/demo/agw/RibbonBar.py +++ b/demo/agw/RibbonBar.py @@ -12,10 +12,10 @@ except: sys.path.append(os.path.split(dirName)[0]) -##try: -from agw import ribbon as RB -##except ImportError: # if it's not there locally, try the wxPython lib. -## import wx.lib.agw.ribbon as RB +try: + from agw import ribbon as RB +except ImportError: # if it's not there locally, try the wxPython lib. + import wx.lib.agw.ribbon as RB from wx.lib.embeddedimage import PyEmbeddedImage @@ -230,7 +230,7 @@ triangle = PyEmbeddedImage( def CreateBitmap(xpm): bmp = eval(xpm).Bitmap - + return bmp @@ -239,7 +239,7 @@ def CreateBitmap(xpm): class ColourClientData(object): def __init__(self, name, colour): - + self._name = name self._colour = colour @@ -248,7 +248,7 @@ class ColourClientData(object): return self._name - + def GetColour(self): return self._colour @@ -264,16 +264,16 @@ class RibbonFrame(wx.Frame): wx.Frame.__init__(self, parent, id, title, pos, size, style) panel = wx.Panel(self) - + self._ribbon = RB.RibbonBar(panel, wx.ID_ANY, agwStyle=RB.RIBBON_BAR_DEFAULT_STYLE|RB.RIBBON_BAR_SHOW_PANEL_EXT_BUTTONS) self._bitmap_creation_dc = wx.MemoryDC() self._colour_data = wx.ColourData() - + home = RB.RibbonPage(self._ribbon, wx.ID_ANY, "Examples", CreateBitmap("ribbon")) toolbar_panel = RB.RibbonPanel(home, wx.ID_ANY, "Toolbar", wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, agwStyle=RB.RIBBON_PANEL_NO_AUTO_MINIMISE|RB.RIBBON_PANEL_EXT_BUTTON) - + toolbar = RB.RibbonToolBar(toolbar_panel, ID_MAIN_TOOLBAR) toolbar.AddTool(wx.ID_ANY, CreateBitmap("align_left")) toolbar.AddTool(wx.ID_ANY, CreateBitmap("align_center")) @@ -338,7 +338,7 @@ class RibbonFrame(wx.Frame): sizer_panelsizer.Add(sizer_panelcombo2, 0, wx.ALL|wx.EXPAND, 2) sizer_panelsizer.AddStretchSpacer(1) sizer_panel.SetSizer(sizer_panelsizer) - + label_font = wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_LIGHT) self._bitmap_creation_dc.SetFont(label_font) @@ -352,13 +352,13 @@ class RibbonFrame(wx.Frame): wx.ArtProvider.GetBitmap(wx.ART_QUESTION, wx.ART_OTHER, wx.Size(32, 32)), "") provider_bar.AddSimpleButton(ID_AUI_PROVIDER, "AUI Provider", CreateBitmap("aui_style"), "") provider_bar.AddSimpleButton(ID_MSW_PROVIDER, "MSW Provider", CreateBitmap("msw_style"), "") - + primary_panel = RB.RibbonPanel(scheme, wx.ID_ANY, "Primary Colour", CreateBitmap("colours")) self._primary_gallery = self.PopulateColoursPanel(primary_panel, self._default_primary, ID_PRIMARY_COLOUR) secondary_panel = RB.RibbonPanel(scheme, wx.ID_ANY, "Secondary Colour", CreateBitmap("colours")) self._secondary_gallery = self.PopulateColoursPanel(secondary_panel, self._default_secondary, ID_SECONDARY_COLOUR) - + dummy_2 = RB.RibbonPage(self._ribbon, wx.ID_ANY, "Empty Page", CreateBitmap("empty")) dummy_3 = RB.RibbonPage(self._ribbon, wx.ID_ANY, "Another Page", CreateBitmap("empty")) @@ -369,7 +369,7 @@ class RibbonFrame(wx.Frame): self._togglePanels = wx.ToggleButton(panel, ID_TOGGLE_PANELS, "&Toggle panels") self._togglePanels.SetValue(True) - + s = wx.BoxSizer(wx.VERTICAL) s.Add(self._ribbon, 0, wx.EXPAND) @@ -384,12 +384,12 @@ class RibbonFrame(wx.Frame): self.SetIcon(images.Mondrian.Icon) self.CenterOnScreen() self.Show() - + def BindEvents(self, bars): selection, shapes, provider_bar, toolbar_panel = bars - + provider_bar.Bind(RB.EVT_RIBBONBUTTONBAR_CLICKED, self.OnDefaultProvider, id=ID_DEFAULT_PROVIDER) provider_bar.Bind(RB.EVT_RIBBONBUTTONBAR_CLICKED, self.OnAUIProvider, id=ID_AUI_PROVIDER) provider_bar.Bind(RB.EVT_RIBBONBUTTONBAR_CLICKED, self.OnMSWProvider, id=ID_MSW_PROVIDER) @@ -428,48 +428,48 @@ class RibbonFrame(wx.Frame): self.Bind(wx.EVT_MENU, self.OnPositionTopBoth, id=ID_POSITION_TOP_BOTH) self._togglePanels.Bind(wx.EVT_TOGGLEBUTTON, self.OnTogglePanels, id=ID_TOGGLE_PANELS) - + def SetBarStyle(self, agwStyle): self._ribbon.Freeze() self._ribbon.SetAGWWindowStyleFlag(agwStyle) - + pTopSize = self.panel.GetSizer() pToolbar = wx.FindWindowById(ID_MAIN_TOOLBAR) if agwStyle & RB.RIBBON_BAR_FLOW_VERTICAL: - + self._ribbon.SetTabCtrlMargins(10, 10) pTopSize.SetOrientation(wx.HORIZONTAL) if pToolbar: pToolbar.SetRows(3, 5) - + else: - + self._ribbon.SetTabCtrlMargins(50, 20) pTopSize.SetOrientation(wx.VERTICAL) if pToolbar: pToolbar.SetRows(2, 3) - + self._ribbon.Realize() self._ribbon.Thaw() self.panel.Layout() - + def PopulateColoursPanel(self, panel, defc, gallery_id): gallery = wx.FindWindowById(gallery_id, panel) - + if gallery: gallery.Clear() else: gallery = RB.RibbonGallery(panel, gallery_id) - + dc = self._bitmap_creation_dc def_item = self.AddColourToGallery(gallery, "Default", dc, defc) gallery.SetSelection(def_item) - + self.AddColourToGallery(gallery, "BLUE", dc) self.AddColourToGallery(gallery, "BLUE VIOLET", dc) self.AddColourToGallery(gallery, "BROWN", dc) @@ -514,10 +514,10 @@ class RibbonFrame(wx.Frame): def GetGalleryColour(self, gallery, item, name=None): data = gallery.GetItemClientData(item) - + if name != None: name = data.GetName() - + return data.GetColour(), name @@ -529,19 +529,19 @@ class RibbonFrame(wx.Frame): gallery = event.GetGallery() provider = gallery.GetArtProvider() - if event.GetGalleryItem() != None: + if event.GetGalleryItem() != None: if provider == self._ribbon.GetArtProvider(): provider = provider.Clone() gallery.SetArtProvider(provider) - + provider.SetColour(RB.RIBBON_ART_GALLERY_HOVER_BACKGROUND_COLOUR, self.GetGalleryColour(event.GetGallery(), event.GetGalleryItem(), None)[0]) - - else: - if provider != self._ribbon.GetArtProvider(): + + else: + if provider != self._ribbon.GetArtProvider(): gallery.SetArtProvider(self._ribbon.GetArtProvider()) del provider - + def OnPrimaryColourSelect(self, event): @@ -558,7 +558,7 @@ class RibbonFrame(wx.Frame): colour, name = self.GetGalleryColour(event.GetGallery(), event.GetGalleryItem(), "") self.AddText("Colour %s selected as secondary."%name) - + primary, dummy, tertiary = self._ribbon.GetArtProvider().GetColourScheme(1, None, 1) self._ribbon.GetArtProvider().SetColourScheme(primary, colour, tertiary) self.ResetGalleryArtProviders() @@ -569,10 +569,10 @@ class RibbonFrame(wx.Frame): if self._primary_gallery.GetArtProvider() != self._ribbon.GetArtProvider(): self._primary_gallery.SetArtProvider(self._ribbon.GetArtProvider()) - - if self._secondary_gallery.GetArtProvider() != self._ribbon.GetArtProvider(): + + if self._secondary_gallery.GetArtProvider() != self._ribbon.GetArtProvider(): self._secondary_gallery.SetArtProvider(self._ribbon.GetArtProvider()) - + def OnSelectionExpandHButton(self, event): @@ -595,7 +595,7 @@ class RibbonFrame(wx.Frame): def OnCrossButton(self, event): - + self.AddText("Cross button clicked.") @@ -751,8 +751,8 @@ class RibbonFrame(wx.Frame): def OnExtButton(self, event): wx.MessageBox("Extended button activated") - - + + def AddText(self, msg): self._logwindow.AppendText(msg) @@ -765,17 +765,17 @@ class RibbonFrame(wx.Frame): item = None if colour != "Default": - c = wx.NamedColour(colour) - + c = wx.Colour(colour) + if value is not None: c = value - + if c.IsOk(): - + iWidth = 64 iHeight = 40 - bitmap = wx.EmptyBitmap(iWidth, iHeight) + bitmap = wx.Bitmap(iWidth, iHeight) dc.SelectObject(bitmap) b = wx.Brush(c) dc.SetPen(wx.BLACK_PEN) @@ -789,20 +789,20 @@ class RibbonFrame(wx.Frame): notcblue = min(abs(~c.Blue()), 255) foreground = wx.Colour(notcred, notcgreen, notcblue) - + if abs(foreground.Red() - c.Red()) + abs(foreground.Blue() - c.Blue()) + abs(foreground.Green() - c.Green()) < 64: # Foreground too similar to background - use a different # strategy to find a contrasting colour foreground = wx.Colour((c.Red() + 64) % 256, 255 - c.Green(), (c.Blue() + 192) % 256) - + dc.SetTextForeground(foreground) dc.DrawText(colour, (iWidth - size.GetWidth() + 1) / 2, (iHeight - size.GetHeight()) / 2) dc.SelectObjectAsSource(wx.NullBitmap) item = gallery.Append(bitmap, wx.ID_ANY) gallery.SetItemClientData(item, ColourClientData(colour, c)) - + return item @@ -815,11 +815,11 @@ class RibbonFrame(wx.Frame): self._ribbon.DismissExpandedPanel() if gallery.GetSelection(): self._colour_data.SetColour(self.GetGalleryColour(gallery, gallery.GetSelection(), None)[0]) - + dlg = wx.ColourDialog(self, self._colour_data) - + if dlg.ShowModal() == wx.ID_OK: - + self._colour_data = dlg.GetColourData() clr = self._colour_data.GetColour() @@ -831,13 +831,13 @@ class RibbonFrame(wx.Frame): break else: item = None - + # Colour not in gallery - add it - if item == None: + if item == None: item = self.AddColourToGallery(gallery, clr.GetAsString(wx.C2S_HTML_SYNTAX), self._bitmap_creation_dc, clr) gallery.Realize() - + # Set selection gallery.EnsureVisible(item) gallery.SetSelection(item) @@ -848,7 +848,7 @@ class RibbonFrame(wx.Frame): dummy.SetGallery(gallery) dummy.SetGalleryItem(item) self.GetEventHandler().ProcessEvent(dummy) - + def OnDefaultProvider(self, event): @@ -915,7 +915,7 @@ def runTest(frame, nb, log): overview = RB.__doc__ -if __name__ == '__main__': +if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) diff --git a/demo/agw/RulerCtrl.py b/demo/agw/RulerCtrl.py index 8c11057b..b797bd90 100644 --- a/demo/agw/RulerCtrl.py +++ b/demo/agw/RulerCtrl.py @@ -82,7 +82,7 @@ class PythonSTC(stc.StyledTextCtrl): self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold") # Python styles - # Default + # Default self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces) # Comments self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces) @@ -116,8 +116,8 @@ class PythonSTC(stc.StyledTextCtrl): # Some methods to make it compatible with how the wxTextCtrl is used def SetValue(self, value): - if wx.USE_UNICODE: - value = value.decode('iso8859_1') + # if wx.USE_UNICODE: + # value = value.decode('iso8859_1') self.SetReadOnly(False) self.SetText(value) @@ -131,7 +131,7 @@ class RulerCtrlDemo(wx.Frame): wx.Frame.__init__(self, parent) self.panel = wx.Panel(self, -1) - statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + statusbar = self.CreateStatusBar(2) statusbar.SetStatusWidths([-2, -1]) # statusbar fields statusbar_fields = [("RulerCtrl wxPython Demo, Andrea Gavana @ 03 Nov 2006"), @@ -144,8 +144,8 @@ class RulerCtrlDemo(wx.Frame): self.LayoutItems() self.SetIcon(images.Mondrian.GetIcon()) - sizex = wx.SystemSettings_GetMetric(wx.SYS_SCREEN_X) - sizey = wx.SystemSettings_GetMetric(wx.SYS_SCREEN_Y) + sizex = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X) + sizey = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y) self.SetSize((3*sizex/4, 3*sizey/4)) self.SendSizeEvent() @@ -312,7 +312,7 @@ class RulerCtrlDemo(wx.Frame): event.Skip() - # Try to emulate the rulers inside a text editor + # Try to emulate the rulers inside a text editor wx.CallAfter(self.SizeRulers) @@ -323,9 +323,9 @@ class RulerCtrlDemo(wx.Frame): def SizeRulers(self): - dc = wx.MemoryDC() + dc = wx.MemoryDC() width, height = self.stc.GetSize() - dc.SelectObject(wx.EmptyBitmap(width, height)) + dc.SelectObject(wx.Bitmap(width, height)) widthMM, heightMM = dc.GetSizeMM() dc.SelectObject(wx.NullBitmap) @@ -351,7 +351,7 @@ class RulerCtrlDemo(wx.Frame): event.Skip() - def OnLabelMinor(self, event): + def OnLabelMinor(self, event): self.ruler3.LabelMinor(event.IsChecked()) event.Skip() @@ -370,12 +370,12 @@ class RulerCtrlDemo(wx.Frame): def OnTickColour(self, event): - self.ruler3.SetTickPenColour(event.GetValue()) + self.ruler3.SetTickPenColour(event.GetValue()) def OnLabelColour(self, event): - self.ruler3.SetLabelColour(event.GetValue()) + self.ruler3.SetLabelColour(event.GetValue()) def CreateMenu(self): @@ -386,11 +386,11 @@ class RulerCtrlDemo(wx.Frame): item = wx.MenuItem(fileMenu, wx.ID_ANY, "E&xit") self.Bind(wx.EVT_MENU, self.OnQuit, item) - fileMenu.AppendItem(item) + fileMenu.Append(item) item = wx.MenuItem(helpMenu, wx.ID_ANY, "About") self.Bind(wx.EVT_MENU, self.OnAbout, item) - helpMenu.AppendItem(item) + helpMenu.Append(item) menuBar.Append(fileMenu, "&File") menuBar.Append(helpMenu, "&Help") diff --git a/demo/agw/ShapedButton.py b/demo/agw/ShapedButton.py index 78ec7906..21fb09ef 100644 --- a/demo/agw/ShapedButton.py +++ b/demo/agw/ShapedButton.py @@ -36,31 +36,31 @@ class ShapedButtonDemo(wx.Frame): wx.Frame.__init__(self, parent, title="ShapedButton wxPython Demo ;-)") # Create Some Maquillage For The Demo: Icon, StatusBar, MenuBar... - + self.SetIcon(images.Mondrian.GetIcon()) - self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-2, -1]) - + statusbar_fields = [("wxPython ShapedButton Demo, Andrea Gavana @ 18 Oct 2005"), ("Welcome To wxPython!")] - + for i in range(len(statusbar_fields)): self.statusbar.SetStatusText(statusbar_fields[i], i) - + self.SetMenuBar(self.CreateMenuBar()) - + framesizer = wx.BoxSizer(wx.VERTICAL) self.panel = wx.Panel(self, -1) mainsizer = wx.BoxSizer(wx.VERTICAL) hsizer0 = wx.BoxSizer(wx.HORIZONTAL) - - sb0 = wx.StaticBox(self.panel, -1) + + sb0 = wx.StaticBox(self.panel, -1) recordsizer = wx.StaticBoxSizer(sb0, wx.HORIZONTAL) # Make A ToolBar-Like Audio Control With Round Buttons/Toggles self.BuildAudioToolBar() - + recordsizer.Add(self.rewind, 0, wx.LEFT, 3) recordsizer.Add(self.play, 0, wx.LEFT, 3) recordsizer.Add(self.record, 0, wx.LEFT, 3) @@ -82,42 +82,42 @@ class ShapedButtonDemo(wx.Frame): smallsizer.Add((0, 1), 1, wx.EXPAND) smallsizer.Add(self.eventtext, 1, wx.EXPAND) smallsizer.Add((0, 1), 1, wx.EXPAND) - + hsizer0.Add(recordsizer, 1, wx.EXPAND) hsizer0.Add(smallsizer, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 5) mainsizer.Add(hsizer0, 0, wx.BOTTOM, 5) mainsizer.Add((0, 10), 0, wx.EXPAND) hsizer = wx.BoxSizer(wx.HORIZONTAL) - + # Make 9 SBitmapButtons With Text Rotation And Different Colours sb1 = wx.StaticBox(self.panel, -1, "Some Buttons") vsizer1 = wx.StaticBoxSizer(sb1, wx.VERTICAL) bsizer = self.BuildNineButtons() - vsizer1.Add((0, 10), 0) + vsizer1.Add((0, 10), 0) vsizer1.Add(bsizer, 1, wx.EXPAND) vsizer1.Add((0, 10), 0) - hsizer.Add(vsizer1, 3, wx.EXPAND) + hsizer.Add(vsizer1, 3, wx.EXPAND) # Make Some Mixed SButton/SToggle With Bitmap And Text Rotation - sb2 = wx.StaticBox(self.panel, -1, "Other Buttons") + sb2 = wx.StaticBox(self.panel, -1, "Other Buttons") vsizer2 = wx.StaticBoxSizer(sb2, wx.VERTICAL) btsizer = self.BuildMixedButtons() - vsizer2.Add((0, 10), 0) + vsizer2.Add((0, 10), 0) vsizer2.Add(btsizer, 1, wx.EXPAND) vsizer2.Add((0, 10), 0) hsizer.Add(vsizer2, 2, wx.EXPAND) # Build Buttons With Elliptic Shape - sb3 = wx.StaticBox(self.panel, -1, "Elliptic Buttons") + sb3 = wx.StaticBox(self.panel, -1, "Elliptic Buttons") vsizer3 = wx.StaticBoxSizer(sb3, wx.VERTICAL) esizer = self.BuildEllipticButtons() - vsizer3.Add((0, 10), 0) + vsizer3.Add((0, 10), 0) vsizer3.Add(esizer, 1, wx.EXPAND) vsizer3.Add((0, 10), 0) hsizer.Add(vsizer3, 2, wx.EXPAND) - + mainsizer.Add(hsizer, 1, wx.EXPAND | wx.ALL, 5) self.panel.SetSizer(mainsizer) @@ -130,7 +130,7 @@ class ShapedButtonDemo(wx.Frame): self.Layout() self.CenterOnParent() - + def BuildAudioToolBar(self): @@ -141,8 +141,8 @@ class ShapedButtonDemo(wx.Frame): self.rewind.SetUseFocusIndicator(False) self.rewind.SetBitmapDisabled(disbmp) - self.rewind.Bind(wx.EVT_BUTTON, self.OnRewind) - + self.rewind.Bind(wx.EVT_BUTTON, self.OnRewind) + # The Play Button Is A Toggle Bitmap Button (SBitmapToggleButton) upbmp = wx.Bitmap(os.path.join(bitmapDir, "play.png"), wx.BITMAP_TYPE_PNG) disbmp = wx.Bitmap(os.path.join(bitmapDir, "playdisabled.png"), wx.BITMAP_TYPE_PNG) @@ -150,7 +150,7 @@ class ShapedButtonDemo(wx.Frame): self.play.SetUseFocusIndicator(False) self.play.SetBitmapDisabled(disbmp) - self.play.Bind(wx.EVT_BUTTON, self.OnPlay) + self.play.Bind(wx.EVT_BUTTON, self.OnPlay) # The Record Button Is A Toggle Bitmap Button (SBitmapToggleButton) upbmp = wx.Bitmap(os.path.join(bitmapDir, "record.png"), wx.BITMAP_TYPE_PNG) @@ -159,7 +159,7 @@ class ShapedButtonDemo(wx.Frame): self.record.SetUseFocusIndicator(False) self.record.SetBitmapDisabled(disbmp) - self.record.Bind(wx.EVT_BUTTON, self.OnRecord) + self.record.Bind(wx.EVT_BUTTON, self.OnRecord) # The Pause Button Is A Toggle Bitmap Button (SBitmapToggleButton) upbmp = wx.Bitmap(os.path.join(bitmapDir, "pause.png"), wx.BITMAP_TYPE_PNG) @@ -179,7 +179,7 @@ class ShapedButtonDemo(wx.Frame): self.stop.SetBitmapDisabled(disbmp) self.stop.Enable(False) - self.stop.Bind(wx.EVT_BUTTON, self.OnStop) + self.stop.Bind(wx.EVT_BUTTON, self.OnStop) # The FFWD Button Is A Simple Bitmap Button (SBitmapButton) upbmp = wx.Bitmap(os.path.join(bitmapDir, "ffwd.png"), wx.BITMAP_TYPE_PNG) @@ -188,22 +188,22 @@ class ShapedButtonDemo(wx.Frame): self.ffwd.SetUseFocusIndicator(False) self.ffwd.SetBitmapDisabled(disbmp) - self.ffwd.Bind(wx.EVT_BUTTON, self.OnFFWD) + self.ffwd.Bind(wx.EVT_BUTTON, self.OnFFWD) def BuildNineButtons(self): # We Build 9 Buttons With Different Colours And A Nice Text Rotation - colours = [None, wx.BLUE, wx.RED, wx.GREEN, wx.NamedColour("Gold"), - wx.NamedColour("Cyan"), wx.NamedColour("Yellow"), - wx.NamedColour("Orange"), wx.NamedColour("Magenta")] + colours = [None, wx.BLUE, wx.RED, wx.GREEN, wx.Colour("Gold"), + wx.CYAN, wx.YELLOW, + wx.Colour("Orange"), wx.Colour("Magenta")] labels = ["These", "Are", "Some", "Nice", "Text", "Appended", "To Different", "Buttons", "Nice Eh?"] fnt = self.GetFont() - + fonts = [fnt, wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD), wx.Font(10, wx.TELETYPE, wx.NORMAL, wx.NORMAL), wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, True), @@ -211,14 +211,14 @@ class ShapedButtonDemo(wx.Frame): wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False, "Tahoma"), fnt, wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, True, "Verdana")] - lcolours = [None, wx.WHITE, wx.NamedColour("Yellow"), wx.WHITE, + lcolours = [None, wx.WHITE, wx.Colour("Yellow"), wx.WHITE, None, None, wx.BLUE, wx.WHITE, wx.WHITE] bsizer = wx.FlexGridSizer(3, 3, 5, 5) rotation = [] for ii in xrange(9): - + btn = SButton(self.panel, -1, labels[ii]) btn.SetButtonColour(colours[ii]) btn.SetFont(fonts[ii]) @@ -239,8 +239,8 @@ class ShapedButtonDemo(wx.Frame): self.buttonlabels = labels self.buttonrotation = rotation - - return bsizer + + return bsizer def BuildMixedButtons(self): @@ -248,28 +248,28 @@ class ShapedButtonDemo(wx.Frame): # Here We Build Some Buttons/Toggles With Different Properties # Notice That We Put Some Images Also For The "Selected" State # For A Button - + btsizer = wx.FlexGridSizer(2, 2, 5, 5) - bmp = wx.Bitmap(os.path.join(bitmapDir, "italy.gif"), wx.BITMAP_TYPE_GIF) + bmp = wx.Bitmap(os.path.join(bitmapDir, "italy.gif"), wx.BITMAP_TYPE_GIF) btn1 = SBitmapButton(self.panel, -1, bmp) - bmp = wx.Bitmap(os.path.join(bitmapDir, "canada.gif"), wx.BITMAP_TYPE_GIF) + bmp = wx.Bitmap(os.path.join(bitmapDir, "canada.gif"), wx.BITMAP_TYPE_GIF) btn1.SetBitmapSelected(bmp) - btn1.Bind(wx.EVT_BUTTON, self.OnItalyCanada) + btn1.Bind(wx.EVT_BUTTON, self.OnItalyCanada) - bmp = wx.Bitmap(os.path.join(bitmapDir, "stop.png"), wx.BITMAP_TYPE_PNG) + bmp = wx.Bitmap(os.path.join(bitmapDir, "stop.png"), wx.BITMAP_TYPE_PNG) btn2 = SBitmapTextToggleButton(self.panel, -1, bmp, "Toggle!") - bmp = wx.Bitmap(os.path.join(bitmapDir, "play.png"), wx.BITMAP_TYPE_PNG) + bmp = wx.Bitmap(os.path.join(bitmapDir, "play.png"), wx.BITMAP_TYPE_PNG) btn2.SetBitmapSelected(bmp) btn2.Bind(wx.EVT_BUTTON, self.OnTogglePlayStop) btn3 = SButton(self.panel, -1, "Rotated") - btn3.SetButtonColour(wx.NamedColour("Cyan")) + btn3.SetButtonColour(wx.Colour("Cyan")) btn3.SetLabelColour(wx.WHITE) btn3.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD, False)) btn3.SetAngleOfRotation(90) btn3.Bind(wx.EVT_BUTTON, self.OnRotated1) - + btn4 = SButton(self.panel, -1, "Button!") btn4.SetAngleOfRotation(45) btn4.Bind(wx.EVT_BUTTON, self.OnRotated1) @@ -285,14 +285,14 @@ class ShapedButtonDemo(wx.Frame): btsizer.AddGrowableCol(1) return btsizer - + def BuildEllipticButtons(self): # Here We Build Elliptic Buttons. Elliptic Buttons Are Somewhat # More Hostiles To Handle, Probably Because My Implementation # Is Lacking Somewhere, But They Look Nice However. - + esizer = wx.FlexGridSizer(2, 2, 5, 5) btn1 = SButton(self.panel, -1, "Ellipse 1") @@ -309,18 +309,18 @@ class ShapedButtonDemo(wx.Frame): btn2.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD, True)) btn2.Bind(wx.EVT_BUTTON, self.OnEllipse) - bmp = wx.Bitmap(os.path.join(bitmapDir, "ffwd.png"), wx.BITMAP_TYPE_PNG) + bmp = wx.Bitmap(os.path.join(bitmapDir, "ffwd.png"), wx.BITMAP_TYPE_PNG) btn3 = SBitmapTextToggleButton(self.panel, -1, bmp, "FFWD") bmp = wx.Bitmap(os.path.join(bitmapDir, "rewind.png"), wx.BITMAP_TYPE_PNG) btn3.SetBitmapSelected(bmp) btn3.SetEllipseAxis(1.4, 1) btn3.Bind(wx.EVT_BUTTON, self.OnFFWDRewind) - bmp = wx.Bitmap(os.path.join(bitmapDir, "round.png"), wx.BITMAP_TYPE_PNG) + bmp = wx.Bitmap(os.path.join(bitmapDir, "round.png"), wx.BITMAP_TYPE_PNG) btn4 = SBitmapButton(self.panel, -1, bmp) btn4.SetEllipseAxis(1, 1.4) btn4.Bind(wx.EVT_BUTTON, self.OnRound) - + esizer.Add(btn1, 1, wx.EXPAND | wx.ALL, 5) esizer.Add(btn2, 1, wx.EXPAND | wx.ALL, 5) esizer.Add(btn3, 1, wx.EXPAND | wx.ALL, 5) @@ -332,32 +332,32 @@ class ShapedButtonDemo(wx.Frame): esizer.AddGrowableCol(1) return esizer - + def CreateMenuBar(self): file_menu = wx.Menu() - - AS_EXIT = wx.NewId() + + AS_EXIT = wx.NewId() file_menu.Append(AS_EXIT, "&Exit") self.Bind(wx.EVT_MENU, self.OnClose, id=AS_EXIT) help_menu = wx.Menu() - AS_ABOUT = wx.NewId() + AS_ABOUT = wx.NewId() help_menu.Append(AS_ABOUT, "&About...") self.Bind(wx.EVT_MENU, self.OnAbout, id=AS_ABOUT) menu_bar = wx.MenuBar() menu_bar.Append(file_menu, "&File") - menu_bar.Append(help_menu, "&Help") + menu_bar.Append(help_menu, "&Help") - return menu_bar + return menu_bar def OnClose(self, event): - + self.Destroy() @@ -369,19 +369,19 @@ class ShapedButtonDemo(wx.Frame): "To Me At The Following Adresses:\n\n" + \ "andrea.gavana@agip.it\n" + "andrea_gavana@tin.it\n\n" + \ "Welcome To wxPython " + wx.VERSION_STRING + "!!" - + dlg = wx.MessageDialog(self, msg, "ShapedButton Demo", wx.OK | wx.ICON_INFORMATION) - + dlg.ShowModal() dlg.Destroy() - + def OnRewind(self, event): self.eventtext.SetLabel("Rewind Button!") self.eventtext.Refresh() - + event.Skip() @@ -401,7 +401,7 @@ class ShapedButtonDemo(wx.Frame): self.rewind.Enable(False) self.ffwd.Enable(False) self.record.Enable(False) - + event.Skip() @@ -418,7 +418,7 @@ class ShapedButtonDemo(wx.Frame): event.Skip() return - + self.eventtext.SetLabel("What Are You Recording? ;-)") self.eventtext.Refresh() self.stop.Enable(True) @@ -426,7 +426,7 @@ class ShapedButtonDemo(wx.Frame): self.rewind.Enable(False) self.ffwd.Enable(False) self.play.Enable(False) - + event.Skip() @@ -436,9 +436,9 @@ class ShapedButtonDemo(wx.Frame): self.eventtext.SetLabel("Pausing Play Or Recording...") else: self.eventtext.SetLabel("Playing After A Pause...") - + self.eventtext.Refresh() - + event.Skip() @@ -446,7 +446,7 @@ class ShapedButtonDemo(wx.Frame): self.eventtext.SetLabel("Everything Stopped") self.eventtext.Refresh() - + self.stop.Enable(False) self.pause.Enable(False) self.rewind.Enable(True) @@ -456,7 +456,7 @@ class ShapedButtonDemo(wx.Frame): self.play.SetToggle(False) self.pause.SetToggle(False) self.record.SetToggle(False) - + event.Skip() @@ -464,10 +464,10 @@ class ShapedButtonDemo(wx.Frame): self.eventtext.SetLabel("Fast Forward Button!") self.eventtext.Refresh() - + event.Skip() - - + + def OnNineButtons(self, event): btn = event.GetEventObject() @@ -475,10 +475,10 @@ class ShapedButtonDemo(wx.Frame): mystr = "Button: " + label + ", Rotation: " + \ str(int(btn.GetAngleOfRotation())) + " Degrees" - + self.eventtext.SetLabel(mystr) self.eventtext.Refresh() - + event.Skip() @@ -486,7 +486,7 @@ class ShapedButtonDemo(wx.Frame): self.eventtext.SetLabel("Italy VS Canada ;-)") self.eventtext.Refresh() - + event.Skip() @@ -500,7 +500,7 @@ class ShapedButtonDemo(wx.Frame): self.eventtext.SetLabel(label) self.eventtext.Refresh() - event.Skip() + event.Skip() def OnRotated1(self, event): @@ -513,10 +513,10 @@ class ShapedButtonDemo(wx.Frame): self.eventtext.SetLabel(mystr) self.eventtext.Refresh() - btn.SetAngleOfRotation(random.randint(0, 359)) - + btn.SetAngleOfRotation(random.randint(0, 359)) + event.Skip() - + def OnEllipse(self, event): @@ -529,12 +529,12 @@ class ShapedButtonDemo(wx.Frame): self.eventtext.Refresh() event.Skip() - + def OnFFWDRewind(self, event): btn = event.GetEventObject() - + if event.GetIsDown(): label = "Let's Rewind Everything" btn.SetLabel("REW") @@ -544,7 +544,7 @@ class ShapedButtonDemo(wx.Frame): self.eventtext.SetLabel(label) self.eventtext.Refresh() - + event.Skip() @@ -594,7 +594,7 @@ def runTest(frame, nb, log): overview = docs -if __name__ == '__main__': +if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) diff --git a/demo/agw/ShortcutEditor.py b/demo/agw/ShortcutEditor.py index b8a9ccb5..f6619eb8 100644 --- a/demo/agw/ShortcutEditor.py +++ b/demo/agw/ShortcutEditor.py @@ -260,7 +260,7 @@ class ShortcutEditorDemo(wx.Frame): recursive = '' - top_menu.AppendItem(sub_menu) + top_menu.Append(sub_menu) if random.randint(0, 1) == 1 and index < num_menus - 1: # Append a separator diff --git a/demo/agw/SpeedMeter.py b/demo/agw/SpeedMeter.py index 2f955510..e0cf5e6b 100644 --- a/demo/agw/SpeedMeter.py +++ b/demo/agw/SpeedMeter.py @@ -24,23 +24,23 @@ except ImportError: # if it's not there locally, try the wxPython lib. #---------------------------------------------------------------------- class SpeedMeterDemo(wx.Panel): - + def __init__(self, parent, log): wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL|wx.NO_FULL_REPAINT_ON_RESIZE) - + panel = wx.Panel(self, -1) sizer = wx.FlexGridSizer(2, 3, 2, 5) # 6 Panels To Hold The SpeedMeters ;-) - + panel1 = wx.Panel(panel, -1, style=wx.SUNKEN_BORDER) panel2 = wx.Panel(panel, -1, style=wx.RAISED_BORDER) panel3 = wx.Panel(panel, -1, style=wx.SUNKEN_BORDER) panel4 = wx.Panel(panel, -1, style=wx.RAISED_BORDER) panel5 = wx.Panel(panel, -1, style=wx.SUNKEN_BORDER) panel6 = wx.Panel(panel, -1, style=wx.RAISED_BORDER) - + # First SpeedMeter: We Use The Following Styles: # # SM_DRAW_HAND: We Want To Draw The Hand (Arrow) Indicator @@ -59,7 +59,7 @@ class SpeedMeterDemo(wx.Panel): # Set The Region Of Existence Of SpeedMeter (Always In Radians!!!!) self.SpeedWindow1.SetAngleRange(-pi/6, 7*pi/6) - # Create The Intervals That Will Divide Our SpeedMeter In Sectors + # Create The Intervals That Will Divide Our SpeedMeter In Sectors intervals = range(0, 201, 20) self.SpeedWindow1.SetIntervals(intervals) @@ -78,7 +78,7 @@ class SpeedMeterDemo(wx.Panel): # Set The Font For The Ticks Markers self.SpeedWindow1.SetTicksFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL)) - + # Set The Text In The Center Of SpeedMeter self.SpeedWindow1.SetMiddleText("Km/h") # Assign The Colour To The Center Text @@ -92,12 +92,12 @@ class SpeedMeterDemo(wx.Panel): # Do Not Draw The External (Container) Arc. Drawing The External Arc May # Sometimes Create Uglier Controls. Try To Comment This Line And See It # For Yourself! - self.SpeedWindow1.DrawExternalArc(False) + self.SpeedWindow1.DrawExternalArc(False) # Set The Current Value For The SpeedMeter self.SpeedWindow1.SetSpeedValue(44) - + # Second SpeedMeter: We Use The Following Styles: # # SM_DRAW_HAND: We Want To Draw The Hand (Arrow) Indicator @@ -108,7 +108,7 @@ class SpeedMeterDemo(wx.Panel): # SM_DRAW_PARTIAL_FILLER: The Region Passed By The Hand Indicator Is Highlighted # With A Different Filling Colour # SM_DRAW_SHADOW: A Shadow For The Hand Indicator Is Drawn - + self.SpeedWindow2 = SM.SpeedMeter(panel2, agwStyle=SM.SM_DRAW_HAND | SM.SM_DRAW_SECTORS | @@ -124,7 +124,7 @@ class SpeedMeterDemo(wx.Panel): intervals = range(0, 13) self.SpeedWindow2.SetIntervals(intervals) - colours = [wx.SystemSettings_GetColour(0)]*12 + colours = [wx.SystemSettings.GetColour(0)]*12 self.SpeedWindow2.SetIntervalColours(colours) ticks = [str(interval) for interval in intervals] @@ -135,7 +135,7 @@ class SpeedMeterDemo(wx.Panel): self.SpeedWindow2.SetTicksFont(wx.Font(11, wx.SCRIPT, wx.NORMAL, wx.BOLD, True)) self.SpeedWindow2.SetNumberOfSecondaryTicks(4) - # Set The Colour For The External Arc + # Set The Colour For The External Arc self.SpeedWindow2.SetArcColour(wx.BLUE) self.SpeedWindow2.SetHandColour(wx.BLACK) @@ -147,7 +147,7 @@ class SpeedMeterDemo(wx.Panel): self.SpeedWindow2.SetSpeedBackground(wx.WHITE) # Set The Colour For The Shadow - self.SpeedWindow2.SetShadowColour(wx.Colour(128, 128, 128)) + self.SpeedWindow2.SetShadowColour(wx.Colour(128, 128, 128)) self.SpeedWindow2.SetSpeedValue(0.0) @@ -157,7 +157,7 @@ class SpeedMeterDemo(wx.Panel): # SM_DRAW_HAND: We Want To Draw The Hand (Arrow) Indicator # SM_DRAW_PARTIAL_SECTORS: Partial Sectors Will Be Drawn, To Indicate Different Intervals # SM_DRAW_MIDDLE_ICON: We Draw An Icon In The Center Of SpeedMeter - + self.SpeedWindow3 = SM.SpeedMeter(panel3, agwStyle=SM.SM_DRAW_HAND | SM.SM_DRAW_PARTIAL_SECTORS | @@ -177,7 +177,7 @@ class SpeedMeterDemo(wx.Panel): ticks = ["F", "", "", "", "E"] self.SpeedWindow3.SetTicks(ticks) self.SpeedWindow3.SetTicksColour(wx.WHITE) - + self.SpeedWindow3.SetHandColour(wx.Colour(255, 255, 0)) # Define The Icon We Want @@ -185,16 +185,16 @@ class SpeedMeterDemo(wx.Panel): icon.SetWidth(24) icon.SetHeight(24) - # Draw The Icon In The Center Of SpeedMeter - self.SpeedWindow3.SetMiddleIcon(icon) + # Draw The Icon In The Center Of SpeedMeter + self.SpeedWindow3.SetMiddleIcon(icon) - self.SpeedWindow3.SetSpeedBackground(wx.BLACK) + self.SpeedWindow3.SetSpeedBackground(wx.BLACK) self.SpeedWindow3.SetArcColour(wx.WHITE) - + self.SpeedWindow3.SetSpeedValue(0.7) - + # Fourth SpeedMeter: We Use The Following Styles: # # SM_DRAW_HAND: We Want To Draw The Hand (Arrow) Indicator @@ -205,7 +205,7 @@ class SpeedMeterDemo(wx.Panel): # NOTE: We Use The Mouse Style mousestyle=SM_MOUSE_TRACK. In This Way, Mouse # Events Are Catched (Mainly Left Clicks/Drags) And You Can Change The Speed # Value Using The Mouse - + self.SpeedWindow4 = SM.SpeedMeter(panel4, agwStyle=SM.SM_DRAW_HAND | SM.SM_DRAW_SECTORS | @@ -229,15 +229,15 @@ class SpeedMeterDemo(wx.Panel): self.SpeedWindow4.SetTicks(ticks) self.SpeedWindow4.SetTicksColour(wx.BLACK) self.SpeedWindow4.SetTicksFont(wx.Font(7, wx.TELETYPE, wx.NORMAL, wx.BOLD)) - + self.SpeedWindow4.SetHandColour(wx.Colour(0, 0, 255)) - self.SpeedWindow4.SetSpeedBackground(wx.SystemSettings_GetColour(0)) + self.SpeedWindow4.SetSpeedBackground(wx.SystemSettings.GetColour(0)) self.SpeedWindow4.DrawExternalArc(False) self.SpeedWindow4.SetHandColour(wx.GREEN) - self.SpeedWindow4.SetShadowColour(wx.Colour(50, 50, 50)) + self.SpeedWindow4.SetShadowColour(wx.Colour(50, 50, 50)) # We Want A Simple Arrow As Indicator, Not The More Scenic Hand ;-) self.SpeedWindow4.SetHandStyle("Arrow") @@ -247,10 +247,10 @@ class SpeedMeterDemo(wx.Panel): icon.SetWidth(16) icon.SetHeight(16) - # Draw The Icon In The Center Of SpeedMeter - self.SpeedWindow4.SetMiddleIcon(icon) + # Draw The Icon In The Center Of SpeedMeter + self.SpeedWindow4.SetMiddleIcon(icon) - # Quite An High Fever!!! + # Quite An High Fever!!! self.SpeedWindow4.SetSpeedValue(41.4) @@ -262,7 +262,7 @@ class SpeedMeterDemo(wx.Panel): # The Main Ticks (Intervals) # SM_DRAW_MIDDLE_TEXT: We Draw Some Text In The Center Of SpeedMeter # SM_ROTATE_TEXT: The Ticks Texts Are Rotated Accordingly To Their Angle - + self.SpeedWindow5 = SM.SpeedMeter(panel5, agwStyle=SM.SM_DRAW_HAND | SM.SM_DRAW_PARTIAL_SECTORS | @@ -289,7 +289,7 @@ class SpeedMeterDemo(wx.Panel): self.SpeedWindow5.SetHandColour(wx.Colour(255, 50, 0)) - self.SpeedWindow5.SetSpeedBackground(wx.SystemSettings_GetColour(0)) + self.SpeedWindow5.SetSpeedBackground(wx.SystemSettings.GetColour(0)) self.SpeedWindow5.DrawExternalArc(False) @@ -298,10 +298,10 @@ class SpeedMeterDemo(wx.Panel): self.SpeedWindow5.SetMiddleText("rpm") self.SpeedWindow5.SetMiddleTextColour(wx.WHITE) self.SpeedWindow5.SetMiddleTextFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD)) - self.SpeedWindow5.SetSpeedBackground(wx.Colour(160, 160, 160)) - + self.SpeedWindow5.SetSpeedBackground(wx.Colour(160, 160, 160)) + self.SpeedWindow5.SetSpeedValue(5.6) - + # Sixth SpeedMeter: That Is Complete And Complex Example. # We Use The Following Styles: @@ -314,7 +314,7 @@ class SpeedMeterDemo(wx.Panel): # Give Some Kind Of Scenic Effect # SM_DRAW_FANCY_TICKS: We Use wx.lib. # SM_DRAW_SHADOW: A Shadow For The Hand Indicator Is Drawn - + self.SpeedWindow6 = SM.SpeedMeter(panel6, agwStyle=SM.SM_DRAW_HAND | SM.SM_DRAW_PARTIAL_FILLER | @@ -340,13 +340,13 @@ class SpeedMeterDemo(wx.Panel): self.SpeedWindow6.DrawExternalArc(False) - self.SpeedWindow6.SetFillerColour(wx.Colour(145, 220, 200)) + self.SpeedWindow6.SetFillerColour(wx.Colour(145, 220, 200)) self.SpeedWindow6.SetShadowColour(wx.BLACK) - self.SpeedWindow6.SetDirection("Reverse") + self.SpeedWindow6.SetDirection("Reverse") - self.SpeedWindow6.SetSpeedBackground(wx.SystemSettings_GetColour(0)) + self.SpeedWindow6.SetSpeedBackground(wx.SystemSettings.GetColour(0)) # Set The First Gradient Colour, Which Is The Colour Near The External Arc self.SpeedWindow6.SetFirstGradientColour(wx.RED) @@ -356,22 +356,22 @@ class SpeedMeterDemo(wx.Panel): icon = wx.Icon(os.path.normpath(os.path.join(bitmapDir, "smpi.ico")), wx.BITMAP_TYPE_ICO) icon.SetHeight(12) icon.SetWidth(12) - self.SpeedWindow6.SetMiddleIcon(icon) - + self.SpeedWindow6.SetMiddleIcon(icon) + self.SpeedWindow6.SetSpeedValue(pi/3) # End Of SpeedMeter Controls Construction. Add Some Functionality self.isalive = 0 - + # These Are Cosmetics For The First SpeedMeter Control bsizer1 = wx.BoxSizer(wx.VERTICAL) - hsizer1 = wx.BoxSizer(wx.HORIZONTAL) - slider = wx.Slider(panel1, -1, 44, 0, 200, size=(-1, 40), + hsizer1 = wx.BoxSizer(wx.HORIZONTAL) + slider = wx.Slider(panel1, -1, 44, 0, 200, size=(-1, 40), style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS ) - slider.SetTickFreq(5, 1) + slider.SetTickFreq(5) slider.Bind(wx.EVT_SCROLL, self.OnSliderScroll) slider.SetToolTip(wx.ToolTip("Drag The Slider To Change The Speed!")) @@ -383,14 +383,14 @@ class SpeedMeterDemo(wx.Panel): # These Are Cosmetics For The Second SpeedMeter Control - + # Create The Timer For The Clock self.timer = wx.PyTimer(self.ClockTimer) self.currvalue = 0 bsizer2 = wx.BoxSizer(wx.VERTICAL) - hsizer2 = wx.BoxSizer(wx.HORIZONTAL) + hsizer2 = wx.BoxSizer(wx.HORIZONTAL) stattext2 = wx.StaticText(panel2, -1, "A Simple Clock", style=wx.ALIGN_CENTER) button2 = wx.Button(panel2, -1, "Stop") @@ -400,27 +400,27 @@ class SpeedMeterDemo(wx.Panel): hsizer2.Add(button2, 0, wx.LEFT, 5) hsizer2.Add(stattext2, 1, wx.EXPAND) - - bsizer2.Add(self.SpeedWindow2, 1, wx.EXPAND) - bsizer2.Add(hsizer2, 0, wx.EXPAND) + + bsizer2.Add(self.SpeedWindow2, 1, wx.EXPAND) + bsizer2.Add(hsizer2, 0, wx.EXPAND) panel2.SetSizer(bsizer2) - + # These Are Cosmetics For The Third SpeedMeter Control self.timer3 = wx.PyTimer(self.OilTimer) bsizer3 = wx.BoxSizer(wx.VERTICAL) - + hsizer3 = wx.BoxSizer(wx.HORIZONTAL) sc = wx.SpinCtrl(panel3, -1, size=(60,20)) sc.SetRange(1, 250) sc.SetValue(50) self.spinctrl = sc - + strs = "Change The Speed And See How Much Fuel You Loose" self.spinctrl.SetToolTip(wx.ToolTip(strs)) - + button3 = wx.Button(panel3, -1, "Refill!", size=(60,20)) button3.SetToolTip(wx.ToolTip("Click Here To Refill!")) button3.Bind(wx.EVT_BUTTON, self.OnRefill) @@ -441,7 +441,7 @@ class SpeedMeterDemo(wx.Panel): stattext4 = wx.StaticText(panel4, -1, "Use The Mouse ;-)") hsizer4.Add(stattext4, 1, wx.EXPAND | wx.LEFT, 5) - + bsizer4.Add(self.SpeedWindow4, 1, wx.EXPAND) bsizer4.Add(hsizer4, 0, wx.EXPAND) panel4.SetSizer(bsizer4) @@ -451,14 +451,14 @@ class SpeedMeterDemo(wx.Panel): bsizer5 = wx.BoxSizer(wx.VERTICAL) hsizer5 = wx.BoxSizer(wx.HORIZONTAL) - + button5 = wx.Button(panel5, -1, "Simulate") button5.SetToolTip(wx.ToolTip("Start A Car Acceleration Simulation")) button5.Bind(wx.EVT_BUTTON, self.OnSimulate) hsizer5.Add(button5, 0, wx.EXPAND | wx.LEFT, 5) hsizer5.Add((1,0), 1, wx.EXPAND) - + bsizer5.Add(self.SpeedWindow5, 1, wx.EXPAND) bsizer5.Add(hsizer5, 0, wx.EXPAND) panel5.SetSizer(bsizer5) @@ -467,46 +467,46 @@ class SpeedMeterDemo(wx.Panel): # These Are Cosmetics For The Sixth SpeedMeter Control bsizer6 = wx.BoxSizer(wx.VERTICAL) hsizer6 = wx.BoxSizer(wx.HORIZONTAL) - + txtctrl6 = wx.TextCtrl(panel6, -1, "60", size=(60, 20)) txtctrl6.SetToolTip(wx.ToolTip("Insert An Angle In DEGREES")) - self.txtctrl = txtctrl6 - + self.txtctrl = txtctrl6 + button6 = wx.Button(panel6, -1, "Go!") button6.SetToolTip(wx.ToolTip("Calculate The Equivalent In Radians And Display It")) hsizer6.Add(txtctrl6, 0, wx.EXPAND | wx.LEFT, 5) hsizer6.Add(button6, 0, wx.EXPAND | wx.LEFT, 5) hsizer6.Add((1,0), 1, wx.EXPAND) - + button6.Bind(wx.EVT_BUTTON, self.OnCalculate) bsizer6.Add(self.SpeedWindow6, 1, wx.EXPAND) bsizer6.Add(hsizer6, 0, wx.EXPAND) panel6.SetSizer(bsizer6) - + bsizer1.Layout() bsizer2.Layout() bsizer3.Layout() bsizer4.Layout() bsizer5.Layout() bsizer6.Layout() - + sizer.Add(panel1, 1, wx.EXPAND) sizer.Add(panel2, 1, wx.EXPAND) sizer.Add(panel3, 1, wx.EXPAND) - + sizer.Add(panel4, 1, wx.EXPAND) sizer.Add(panel5, 1, wx.EXPAND) sizer.Add(panel6, 1, wx.EXPAND) sizer.AddGrowableRow(0) sizer.AddGrowableRow(1) - + sizer.AddGrowableCol(0) sizer.AddGrowableCol(1) sizer.AddGrowableCol(2) - + panel.SetSizer(sizer) mainSizer = wx.BoxSizer(wx.VERTICAL) @@ -516,7 +516,7 @@ class SpeedMeterDemo(wx.Panel): self.timer.Start(1000) self.timer3.Start(500) - + def OnSliderScroll(self, event): @@ -532,14 +532,14 @@ class SpeedMeterDemo(wx.Panel): else: self.currvalue = self.currvalue + 1 - self.SpeedWindow2.SetMiddleText(str(self.currvalue) + " s") + self.SpeedWindow2.SetMiddleText(str(self.currvalue) + " s") self.SpeedWindow2.SetSpeedValue(self.currvalue/5.0) def OnStopClock(self, event): btn = event.GetEventObject() - + if self.stopped == 0: self.stopped = 1 self.timer.Stop() @@ -548,12 +548,12 @@ class SpeedMeterDemo(wx.Panel): self.stopped = 0 self.timer.Start() btn.SetLabel("Stop") - - + + def OilTimer(self): val = self.spinctrl.GetValue() - + if val > 250: return @@ -562,7 +562,7 @@ class SpeedMeterDemo(wx.Panel): if new > 4.0: return - + self.SpeedWindow3.SetSpeedValue(new) @@ -572,7 +572,7 @@ class SpeedMeterDemo(wx.Panel): def OnSimulate(self, event): - + for ii in range(50): self.SpeedWindow5.SetSpeedValue(ii/10.0) wx.MilliSleep(10) @@ -585,12 +585,12 @@ class SpeedMeterDemo(wx.Panel): wx.MilliSleep(50) current = self.SpeedWindow5.GetSpeedValue() - + for ii in range(59): current = current + 1.0/10.0 self.SpeedWindow5.SetSpeedValue(current) - wx.MilliSleep(10) - + wx.MilliSleep(10) + event.Skip() @@ -615,7 +615,7 @@ class SpeedMeterDemo(wx.Panel): end = anglerange[1] error = 0 - + if newval < start: msg = "ERROR: Value Entered In The TextCtrl:\n\n" + myval + "\n\n" msg = msg + "Is Smaller Than Minimum Value." @@ -634,7 +634,7 @@ class SpeedMeterDemo(wx.Panel): return self.SpeedWindow6.SetSpeedValue(newval) - + #---------------------------------------------------------------------- diff --git a/demo/agw/SuperToolTip.py b/demo/agw/SuperToolTip.py index 75730ee3..d351e31d 100644 --- a/demo/agw/SuperToolTip.py +++ b/demo/agw/SuperToolTip.py @@ -38,11 +38,11 @@ class SuperToolTipDemo(wx.Frame): self.stylesCombo = wx.ComboBox(self.mainPanel, -1, choices=STT.GetStyleKeys(), style=wx.CB_DROPDOWN|wx.CB_READONLY) self.customStyles = wx.RadioButton(self.mainPanel, -1, "Custom ") - self.topColourPicker = wx.ColourPickerCtrl(self.mainPanel, col=wx.WHITE) - system = wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVECAPTION) - r, g, b = system - self.middleColourPicker = wx.ColourPickerCtrl(self.mainPanel, col=wx.Colour((255-r)/2, (255-g)/2, (255-b)/2)) - self.bottomColourPicker = wx.ColourPickerCtrl(self.mainPanel, col=system) + self.topColourPicker = wx.ColourPickerCtrl(self.mainPanel, colour=wx.WHITE) + system = wx.SystemSettings.GetColour(wx.SYS_COLOUR_ACTIVECAPTION) + r, g, b, a = system + self.middleColourPicker = wx.ColourPickerCtrl(self.mainPanel, colour=wx.Colour((255-r)/2, (255-g)/2, (255-b)/2)) + self.bottomColourPicker = wx.ColourPickerCtrl(self.mainPanel, colour=system) self.headerCheck = wx.CheckBox(self.mainPanel, -1, "Show Header") self.headerText = wx.TextCtrl(self.mainPanel, -1, "Merge And Center") self.headerBitmap = wx.StaticBitmap(self.mainPanel, -1, @@ -55,7 +55,7 @@ class SuperToolTipDemo(wx.Frame): wx.Bitmap(os.path.normpath(os.path.join(bitmapDir, "sttfont.png")), wx.BITMAP_TYPE_PNG)) msg = "A Bold Title\n\nJoins the selected cells into one larger cell\nand centers the contents in the new cell.\n" \ - "This is often used to create labels that span\nmultiple columns.\n\n


draw a horizontal line - text on same line will be ignored\n\nI am a link{http://xoomer.alice.it/infinity77}" + "This is often used to create labels that span\nmultiple columns.\n\nI am a link{http://xoomer.alice.it/infinity77}" self.bodyText = wx.TextCtrl(self.mainPanel, -1, msg, style=wx.TE_MULTILINE) self.includeCheck = wx.CheckBox(self.mainPanel, -1, "Include Body Image") self.footerCheck = wx.CheckBox(self.mainPanel, -1, "Show Footer") @@ -69,7 +69,7 @@ class SuperToolTipDemo(wx.Frame): self.dropShadow = wx.CheckBox(self.mainPanel, -1, "Rounded Corners And Drop Shadow (Windows XP Only)") self.useFade = wx.CheckBox(self.mainPanel, -1, "Fade In/Fade Out Effects (Windows XP Only)") self.endTimer = wx.SpinCtrl(self.mainPanel, -1, "5") - + btnBmp = wx.Bitmap(os.path.normpath(os.path.join(bitmapDir,"sttbutton.png")), wx.BITMAP_TYPE_PNG) self.toolTipButton = buttons.ThemedGenBitmapTextButton(self.mainPanel, -1, btnBmp, " Big Test Button ", size=(-1, 130)) @@ -87,7 +87,7 @@ class SuperToolTipDemo(wx.Frame): self.generateTip.Bind(wx.EVT_BUTTON, self.OnGenerateTip) self.Bind(wx.EVT_FILEPICKER_CHANGED, self.OnPickBitmap, self.headerFilePicker) self.Bind(wx.EVT_FILEPICKER_CHANGED, self.OnPickBitmap, self.footerFilePicker) - + self.enableWidgets = {} self.enableWidgets[self.headerCheck] = [self.headerBitmap, self.headerFilePicker, @@ -109,15 +109,15 @@ class SuperToolTipDemo(wx.Frame): menuBar = wx.MenuBar(wx.MB_DOCKABLE) fileMenu = wx.Menu() helpMenu = wx.Menu() - + item = wx.MenuItem(fileMenu, wx.ID_ANY, "E&xit", "Exit demo") self.Bind(wx.EVT_MENU, self.OnClose, item) - fileMenu.AppendItem(item) + fileMenu.Append(item) item = wx.MenuItem(helpMenu, wx.ID_ANY, "About...", "Shows The About Dialog") self.Bind(wx.EVT_MENU, self.OnAbout, item) - helpMenu.AppendItem(item) - + helpMenu.Append(item) + menuBar.Append(fileMenu, "&File") menuBar.Append(helpMenu, "&Help") @@ -149,7 +149,7 @@ class SuperToolTipDemo(wx.Frame): mainSizer = wx.BoxSizer(wx.VERTICAL) topSizer = wx.BoxSizer(wx.HORIZONTAL) - otherSizer = wx.StaticBoxSizer(self.otherSizer_staticbox, wx.VERTICAL) + otherSizer = wx.StaticBoxSizer(self.otherSizer_staticbox, wx.VERTICAL) toolTipSizer = wx.StaticBoxSizer(self.toolTipSizer_staticbox, wx.HORIZONTAL) toolTipSizer_1 = wx.BoxSizer(wx.VERTICAL) footerSizer = wx.StaticBoxSizer(self.footerSizer_staticbox, wx.VERTICAL) @@ -172,13 +172,13 @@ class SuperToolTipDemo(wx.Frame): colourSizer_2.Add(self.topColourPicker, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) label_2 = wx.StaticText(self.mainPanel, -1, "Middle:") colourSizer_2.Add(label_2, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 3) - colourSizer_2.Add(self.middleColourPicker, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) + colourSizer_2.Add(self.middleColourPicker, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) label_3 = wx.StaticText(self.mainPanel, -1, "Bottom:") colourSizer_2.Add(label_3, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 3) colourSizer_2.Add(self.bottomColourPicker, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) colourSizer.Add(colourSizer_2, 1, wx.EXPAND, 0) mainSizer.Add(colourSizer, 0, wx.ALL|wx.EXPAND, 5) - + headerSizer.Add(self.headerCheck, 0, wx.ALL, 5) label_4 = wx.StaticText(self.mainPanel, -1, "Header Text:") headerSizer_1.Add(label_4, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) @@ -206,7 +206,7 @@ class SuperToolTipDemo(wx.Frame): topSizer.Add(headerSizer, 1, wx.EXPAND|wx.ALL, 5) topSizer.Add(footerSizer, 1, wx.EXPAND|wx.ALL, 5) mainSizer.Add(topSizer, 0, wx.TOP|wx.BOTTOM|wx.EXPAND, 5) - + bodySizer.Add(self.bodyBitmap, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) bodySizer_2.Add(self.bodyText, 1, wx.EXPAND, 0) bodySizer_2.Add(self.includeCheck, 0, wx.RIGHT|wx.TOP, 5) @@ -221,7 +221,7 @@ class SuperToolTipDemo(wx.Frame): otherSizer.Add((0, 2)) otherSizer.Add(self.endTimer, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM, 5) mainSizer.Add(otherSizer, 0, wx.ALL|wx.EXPAND, 5) - + toolTipSizer.Add(self.toolTipButton, 1, wx.ALL|wx.EXPAND, 5) toolTipSizer_1.Add(self.generateTip, 0, wx.ALL, 5) toolTipSizer.Add(toolTipSizer_1, 0, wx.EXPAND, 0) @@ -234,7 +234,7 @@ class SuperToolTipDemo(wx.Frame): frameSizer.Fit(self) self.Layout() - wx.CallAfter(mainSizer.Layout) + wx.CallAfter(mainSizer.Layout) def OnRadioColours(self, event): @@ -278,7 +278,7 @@ class SuperToolTipDemo(wx.Frame): else: self.footerBitmap.SetBitmap(bmp) self.footerBitmap.Refresh() - + def OnGenerateTip(self, event): @@ -302,7 +302,7 @@ class SuperToolTipDemo(wx.Frame): bodyImage = self.bodyBitmap.GetBitmap() else: bodyImage = wx.NullBitmap - + if self.footerCheck.GetValue() == 0: footerText, footerBmp, drawFLine = "", wx.NullBitmap, False else: @@ -310,7 +310,7 @@ class SuperToolTipDemo(wx.Frame): footerBmp = self.footerBitmap.GetBitmap() drawFLine = self.footerLineCheck.GetValue() - if not hasattr(self, "tip"): + if not hasattr(self, "tip"): self.tip = STT.SuperToolTip(message) else: self.tip.SetMessage(message) @@ -320,7 +320,7 @@ class SuperToolTipDemo(wx.Frame): self.tip.SetHeaderBitmap(headerBmp) self.tip.SetFooter(footerText) self.tip.SetFooterBitmap(footerBmp) - + self.tip.SetTarget(self.toolTipButton) self.tip.SetDrawHeaderLine(drawHLine) self.tip.SetDrawFooterLine(drawFLine) @@ -328,7 +328,7 @@ class SuperToolTipDemo(wx.Frame): self.tip.SetDropShadow(self.dropShadow.GetValue()) self.tip.SetUseFade(self.useFade.GetValue()) self.tip.SetEndDelay(self.endTimer.GetValue()) - + if self.stylesRadio.GetValue(): self.tip.ApplyStyle(styleKey) else: @@ -339,7 +339,7 @@ class SuperToolTipDemo(wx.Frame): def OnClose(self, event): wx.CallAfter(self.Destroy) - + def OnAbout(self, event): @@ -349,17 +349,17 @@ class SuperToolTipDemo(wx.Frame): "to me at the following addresses:\n\n" + \ "andrea.gavana@gmail.com\n" + "andrea.gavana@maerskoil.com\n\n" + \ "Welcome to wxPython " + wx.VERSION_STRING + "!!" - + dlg = wx.MessageDialog(self, msg, "SuperToolTip wxPython Demo", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() - dlg.Destroy() - + dlg.Destroy() + class TestPanel(wx.Panel): def __init__(self, parent, log): - + self.log = log wx.Panel.__init__(self, parent, -1) diff --git a/demo/agw/ThumbnailCtrl.py b/demo/agw/ThumbnailCtrl.py index 55637df5..dd5d2296 100644 --- a/demo/agw/ThumbnailCtrl.py +++ b/demo/agw/ThumbnailCtrl.py @@ -27,7 +27,7 @@ class ThumbnailCtrlDemo(wx.Frame): self.SetIcon(images.Mondrian.GetIcon()) self.SetTitle("ThumbnailCtrl wxPython Demo ;-)") - self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) + self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-2, -1]) # statusbar fields statusbar_fields = [("ThumbnailCtrl Demo, Andrea Gavana @ 10 Dec 2005"), @@ -37,14 +37,14 @@ class ThumbnailCtrlDemo(wx.Frame): self.statusbar.SetStatusText(statusbar_fields[i], i) self.SetMenuBar(self.CreateMenuBar()) - + splitter = wx.SplitterWindow(self, -1, style=wx.CLIP_CHILDREN | wx.SP_3D | wx.WANTS_CHARS | wx.SP_LIVE_UPDATE) self.panel = wx.Panel(splitter, -1) sizer = wx.BoxSizer(wx.HORIZONTAL) scroll = TC.ThumbnailCtrl(splitter, -1, imagehandler=TC.NativeImageHandler) - + scroll.ShowFileNames() if os.path.isdir("../bitmaps"): scroll.ShowDir(os.path.normpath(os.getcwd() + "/../bitmaps")) @@ -53,7 +53,7 @@ class ThumbnailCtrlDemo(wx.Frame): self.TC = scroll self.log = log - + self.thumbsizer_staticbox = wx.StaticBox(self.panel, -1, "Thumb Style") self.customsizer_staticbox = wx.StaticBox(self.panel, -1, "Thumb Customization") self.optionsizer_staticbox = wx.StaticBox(self.panel, -1, "More Options") @@ -79,13 +79,13 @@ class ThumbnailCtrlDemo(wx.Frame): self.radiostyle4] self.thumbstyles = ["THUMB_OUTLINE_NONE", "THUMB_OUTLINE_FULL", "THUMB_OUTLINE_RECT", "THUMB_OUTLINE_IMAGE"] - + self.SetProperties() self.DoLayout() self.panel.SetSizer(sizer) sizer.Layout() - + self.Bind(wx.EVT_RADIOBUTTON, self.OnChangeOutline, self.radiostyle1) self.Bind(wx.EVT_RADIOBUTTON, self.OnChangeOutline, self.radiostyle2) self.Bind(wx.EVT_RADIOBUTTON, self.OnChangeOutline, self.radiostyle3) @@ -105,14 +105,14 @@ class ThumbnailCtrlDemo(wx.Frame): self.TC.Bind(TC.EVT_THUMBNAILS_SEL_CHANGED, self.OnSelChanged) self.TC.Bind(TC.EVT_THUMBNAILS_POINTED, self.OnPointed) self.TC.Bind(TC.EVT_THUMBNAILS_DCLICK, self.OnDClick) - + splitter.SplitVertically(scroll, self.panel, 180) - splitter.SetMinimumPaneSize(140) + splitter.SetMinimumPaneSize(140) self.SetMinSize((700, 590)) self.CenterOnScreen() - + def SetProperties(self): self.radiostyle4.SetValue(1) @@ -125,7 +125,7 @@ class ThumbnailCtrlDemo(wx.Frame): def DoLayout(self): - + splitsizer = wx.BoxSizer(wx.VERTICAL) optionsizer = wx.StaticBoxSizer(self.optionsizer_staticbox, wx.VERTICAL) zoomsizer = wx.BoxSizer(wx.HORIZONTAL) @@ -158,32 +158,32 @@ class ThumbnailCtrlDemo(wx.Frame): self.panel.SetAutoLayout(True) self.panel.SetSizer(splitsizer) splitsizer.Fit(self.panel) - + def CreateMenuBar(self): file_menu = wx.Menu() - - AS_EXIT = wx.NewId() + + AS_EXIT = wx.NewId() file_menu.Append(AS_EXIT, "&Exit") self.Bind(wx.EVT_MENU, self.OnClose, id=AS_EXIT) help_menu = wx.Menu() - AS_ABOUT = wx.NewId() + AS_ABOUT = wx.NewId() help_menu.Append(AS_ABOUT, "&About...") self.Bind(wx.EVT_MENU, self.OnAbout, id=AS_ABOUT) menu_bar = wx.MenuBar() menu_bar.Append(file_menu, "&File") - menu_bar.Append(help_menu, "&Help") + menu_bar.Append(help_menu, "&Help") - return menu_bar + return menu_bar def OnClose(self, event): - + self.Destroy() @@ -195,10 +195,10 @@ class ThumbnailCtrlDemo(wx.Frame): "To Me At The Following Adresses:\n\n" + \ "andrea.gavana@agip.it\n" + "andrea_gavana@tin.it\n\n" + \ "Welcome To wxPython " + wx.VERSION_STRING + "!!" - + dlg = wx.MessageDialog(self, msg, "ThumbnailCtrl Demo", wx.OK | wx.ICON_INFORMATION) - + dlg.SetFont(wx.Font(8, wx.NORMAL, wx.NORMAL, wx.NORMAL, False)) dlg.ShowModal() dlg.Destroy() @@ -212,15 +212,15 @@ class ThumbnailCtrlDemo(wx.Frame): # If the user selects OK, then we process the dialog's data. # This is done by getting the path data from the dialog - BEFORE - # we destroy it. + # we destroy it. if dlg.ShowModal() == wx.ID_OK: self.TC.ShowDir(dlg.GetPath()) self.log.write("OnSetDirectory: directory changed to: %s\n"%dlg.GetPath()) # Only destroy a dialog after you're done with it. dlg.Destroy() - - + + def OnChangeOutline(self, event): # wxGlade: MyFrame. radio = event.GetEventObject() @@ -236,7 +236,7 @@ class ThumbnailCtrlDemo(wx.Frame): self.TC.SetThumbOutline(TC.THUMB_OUTLINE_IMAGE) self.TC.Refresh() - + self.log.write("OnChangeOutline: Outline changed to: %s\n"%self.thumbstyles[pos]) event.Skip() @@ -249,7 +249,7 @@ class ThumbnailCtrlDemo(wx.Frame): else: self.TC.SetHighlightPointed(False) self.log.write("OnHighlight: Don't Highlight thumbs on pointing\n") - + event.Skip() @@ -263,7 +263,7 @@ class ThumbnailCtrlDemo(wx.Frame): self.log.write("OnShowFiles: Thumbs file names not shown\n") self.TC.Refresh() - + event.Skip() @@ -277,9 +277,9 @@ class ThumbnailCtrlDemo(wx.Frame): self.log.write("OnEnableDragging: Thumbs drag and drop disabled\n") self.TC.Refresh() - + event.Skip() - + def OnSetPopup(self, event): # wxGlade: MyFrame. @@ -290,7 +290,7 @@ class ThumbnailCtrlDemo(wx.Frame): else: self.TC.SetPopupMenu(None) self.log.write("OnSetPopup: Popups disabled on thumbs\n") - + event.Skip() @@ -303,7 +303,7 @@ class ThumbnailCtrlDemo(wx.Frame): else: self.TC.SetGlobalPopupMenu(None) self.log.write("OnSetGlobalPopup: Popups disabled globally (no selection needed)\n") - + event.Skip() @@ -329,8 +329,8 @@ class ThumbnailCtrlDemo(wx.Frame): self.TC.EnableToolTips(False) event.Skip() - - + + def OnSetZoom(self, event): # wxGlade: MyFrame. val = self.textzoom.GetValue().strip() @@ -357,7 +357,7 @@ class ThumbnailCtrlDemo(wx.Frame): return self.TC.SetZoomFactor(val) - + event.Skip() @@ -377,7 +377,7 @@ class ThumbnailCtrlDemo(wx.Frame): self.log.write("OnDClick: Thumb double-clicked: %s\n"%self.TC.GetSelection()) event.Skip() - + def OnSetFont(self, event): # wxGlade: MyFrame. @@ -386,17 +386,17 @@ class ThumbnailCtrlDemo(wx.Frame): data.SetInitialFont(self.TC.GetCaptionFont()) dlg = wx.FontDialog(self, data) - + if dlg.ShowModal() == wx.ID_OK: data = dlg.GetFontData() font = data.GetChosenFont() self.TC.SetCaptionFont(font) self.TC.Refresh() self.log.write("OnSetFont: Caption font changed\n") - + # Don't destroy the dialog until you get everything you need from the # dialog! - dlg.Destroy() + dlg.Destroy() event.Skip() @@ -404,7 +404,7 @@ class ThumbnailCtrlDemo(wx.Frame): dlg = wx.ColourDialog(self) - # Ensure the full colour dialog is displayed, + # Ensure the full colour dialog is displayed, # not the abbreviated version. dlg.GetColourData().SetChooseFull(True) @@ -424,7 +424,7 @@ class ThumbnailCtrlDemo(wx.Frame): # Once the dialog is destroyed, Mr. wx.ColourData is no longer your # friend. Don't use it again! dlg.Destroy() - + def CreatePopups(self): @@ -451,15 +451,15 @@ class ThumbnailCtrlDemo(wx.Frame): self.Bind(wx.EVT_MENU, self.OnPopupSeven, id=self.popupID7) self.Bind(wx.EVT_MENU, self.OnPopupEight, id=self.popupID8) self.Bind(wx.EVT_MENU, self.OnPopupNine, id=self.popupID9) - + menu = wx.Menu() item = wx.MenuItem(menu, self.popupID1, "One") img = images.Mondrian.GetImage() img.Rescale(16, 16) bmp = img.ConvertToBitmap() item.SetBitmap(bmp) - menu.AppendItem(item) - + menu.Append(item) + # add some other items menu.Append(self.popupID2, "Two") menu.Append(self.popupID3, "Three") @@ -470,7 +470,7 @@ class ThumbnailCtrlDemo(wx.Frame): sm = wx.Menu() sm.Append(self.popupID8, "Sub Item 1") sm.Append(self.popupID9, "Sub Item 1") - menu.AppendMenu(self.popupID7, "Test Submenu", sm) + menu.Append(self.popupID7, "Test Submenu", sm) return menu @@ -485,10 +485,10 @@ class ThumbnailCtrlDemo(wx.Frame): self.Bind(wx.EVT_MENU, self.OnPopupTen, id=self.popupID10) self.Bind(wx.EVT_MENU, self.OnPopupEleven, id=self.popupID11) self.Bind(wx.EVT_MENU, self.OnPopupTwelve, id=self.popupID12) - + menu = wx.Menu() item = wx.MenuItem(menu, self.popupID10, "Select all") - menu.AppendItem(item) + menu.Append(item) menu.AppendSeparator() item = wx.MenuItem(menu, self.popupID11, "Say Hello!") @@ -496,13 +496,13 @@ class ThumbnailCtrlDemo(wx.Frame): img.Rescale(16, 16) bmp = img.ConvertToBitmap() item.SetBitmap(bmp) - menu.AppendItem(item) + menu.Append(item) menu.AppendSeparator() - + menu.Append(self.popupID12, "Get thumbs count") return menu - + def OnPopupOne(self, event): self.log.write("OnPopupMenu: Popup One\n") @@ -538,7 +538,7 @@ class ThumbnailCtrlDemo(wx.Frame): def OnPopupNine(self, event): self.log.write("OnPopupMenu: Popup Nine\n") - + def OnPopupTen(self, event): @@ -548,14 +548,14 @@ class ThumbnailCtrlDemo(wx.Frame): self.TC.SetSelection(ii) self.log.write("OnGlobalPopupMenu: all thumbs selected\n") - + event.Skip() def OnPopupEleven(self, event): self.log.write("OnGlobalPopupMenu: say hello message...\n") - + msgstr = "Info: let's say hello to wxPython! " dlg = wx.MessageDialog(self, msgstr, "ThumbnailCtrlDemo Info", wx.OK | wx.ICON_INFORMATION) @@ -569,7 +569,7 @@ class ThumbnailCtrlDemo(wx.Frame): items = self.TC.GetItemCount() self.log.write("OnGlobalPopupMenu: number of thumbs: %d\n"%items) - + msgstr = "Info: number of thumbs: %d"%items dlg = wx.MessageDialog(self, msgstr, "ThumbnailCtrlDemo Info", wx.OK | wx.ICON_INFORMATION) @@ -577,8 +577,8 @@ class ThumbnailCtrlDemo(wx.Frame): dlg.Destroy() event.Skip() - - + + #--------------------------------------------------------------------------- diff --git a/demo/agw/ToasterBox.py b/demo/agw/ToasterBox.py index f613fc31..f5974c02 100644 --- a/demo/agw/ToasterBox.py +++ b/demo/agw/ToasterBox.py @@ -23,7 +23,7 @@ except ImportError: # if it's not there locally, try the wxPython lib. # In case of TB_COMPLEX style, create a panel that contains an image, some # text, an hyperlink and a ticker. -import wx.lib.hyperlink as hyperlink +from wx.adv import HyperlinkCtrl as hyperlink from wx.lib.ticker import Ticker # ------------------------------------------------------------------------------ # @@ -327,7 +327,7 @@ class ToasterBoxDemo(scrolled.ScrolledPanel): if os.path.isfile(bmp): dummybmp = wx.Bitmap(bmp) - if dummybmp.Ok(): + if dummybmp.IsOk(): tb.SetPopupBitmap(bmp) else: tb.SetPopupBitmap() diff --git a/demo/agw/UltimateListCtrl.py b/demo/agw/UltimateListCtrl.py index 9322370c..3920e970 100644 --- a/demo/agw/UltimateListCtrl.py +++ b/demo/agw/UltimateListCtrl.py @@ -45,14 +45,14 @@ class ButtonPanel(wx.Panel): self.SetSizer(box) box.Fit(self) - + def OnButton(self, event): - + event.Skip() wx.BeginBusyCursor() - + modName = buttonDefs[event.GetId()][0] module = __import__(modName) frame = module.TestFrame(None, self.log) diff --git a/demo/agw/UltimateReportDemo.py b/demo/agw/UltimateReportDemo.py index cbacfb0b..a39dad82 100644 --- a/demo/agw/UltimateReportDemo.py +++ b/demo/agw/UltimateReportDemo.py @@ -194,21 +194,21 @@ class UltimateRenderer_1(object): def __init__(self, parent): self.progressValue = random.randint(1, 99) - + def DrawSubItem(self, dc, rect, line, highlighted, enabled): """Draw a custom progress bar using double buffering to prevent flicker""" - canvas = wx.EmptyBitmap(rect.width, rect.height) + canvas = wx.Bitmap(rect.width, rect.height) mdc = wx.MemoryDC() mdc.SelectObject(canvas) if highlighted: - mdc.SetBackground(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))) + mdc.SetBackground(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT))) else: - mdc.SetBackground(wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))) + mdc.SetBackground(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))) mdc.Clear() - + self.DrawProgressBar(mdc, 0, 0, rect.width, rect.height, self.progressValue) mdc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD)) @@ -218,17 +218,17 @@ class UltimateRenderer_1(object): dc.SetClippingRegion(rect.x, rect.y, rect.width, rect.height) dc.Blit(rect.x+3, rect.y, rect.width-6, rect.height, mdc, 0, 0) dc.DestroyClippingRegion() - + def GetLineHeight(self): return PIPE_HEIGHT + 6 - + def GetSubItemWidth(self): return 130 - + def UpdateValue(self): @@ -239,7 +239,7 @@ class UltimateRenderer_1(object): def DrawHorizontalPipe(self, dc, x, y, w, colour): """Draws a horizontal 3D-looking pipe.""" - + for r in range(PIPE_HEIGHT): red = int(colour.Red() * math.sin((math.pi/PIPE_HEIGHT)*r)) green = int(colour.Green() * math.sin((math.pi/PIPE_HEIGHT)*r)) @@ -250,26 +250,26 @@ class UltimateRenderer_1(object): def DrawProgressBar(self, dc, x, y, w, h, percent): """ - Draws a progress bar in the (x,y,w,h) box that represents a progress of - 'percent'. The progress bar is only horizontal and it's height is constant - (PIPE_HEIGHT). The 'h' parameter is used to vertically center the progress + Draws a progress bar in the (x,y,w,h) box that represents a progress of + 'percent'. The progress bar is only horizontal and it's height is constant + (PIPE_HEIGHT). The 'h' parameter is used to vertically center the progress bar in the allotted space. - + The drawing is speed-optimized. Two bitmaps are created the first time this function runs - one for the done (green) part of the progress bar and one for the remaining (white) part. During normal operation the function just cuts the necessary part of the two bitmaps and draws them. """ - + # Create two pipes if self.DONE_BITMAP is None: - self.DONE_BITMAP = wx.EmptyBitmap(PIPE_WIDTH, PIPE_HEIGHT) + self.DONE_BITMAP = wx.Bitmap(PIPE_WIDTH, PIPE_HEIGHT) mdc = wx.MemoryDC() mdc.SelectObject(self.DONE_BITMAP) self.DrawHorizontalPipe(mdc, 0, 0, PIPE_WIDTH, wx.GREEN) mdc.SelectObject(wx.NullBitmap) - self.REMAINING_BITMAP = wx.EmptyBitmap(PIPE_WIDTH, PIPE_HEIGHT) + self.REMAINING_BITMAP = wx.Bitmap(PIPE_WIDTH, PIPE_HEIGHT) mdc = wx.MemoryDC() mdc.SelectObject(self.REMAINING_BITMAP) self.DrawHorizontalPipe(mdc, 0, 0, PIPE_WIDTH, wx.RED) @@ -277,7 +277,7 @@ class UltimateRenderer_1(object): mdc.SelectObject(wx.NullBitmap) # Center the progress bar vertically in the box supplied - y = y + (h - PIPE_HEIGHT)/2 + y = y + (h - PIPE_HEIGHT)/2 if percent == 0: middle = 0 @@ -300,7 +300,7 @@ class UltimateRenderer_1(object): class UltimateRenderer_2(object): def __init__(self, parent): - + e = wx.FontEnumerator() e.EnumerateFacenames() fontList = e.GetFacenames() @@ -318,19 +318,19 @@ class UltimateRenderer_2(object): self.width, self.height, descent, el = dc.GetFullTextExtent(self.text) self.height += descent - + def DrawSubItem(self, dc, rect, line, highlighted, enabled): - + dc.SetBackgroundMode(wx.SOLID) dc.SetBrush(wx.Brush(wx.BLACK, wx.SOLID)) dc.SetPen(wx.TRANSPARENT_PEN) - dc.DrawRectangleRect(rect) + dc.DrawRectangle(rect) - dc.SetBackgroundMode(wx.TRANSPARENT) + dc.SetBackgroundMode(wx.TRANSPARENT) dc.SetFont(self.randomFont) - colours = [wx.RED, wx.WHITE, wx.GREEN, wx.NamedColour("SKY BLUE")] + colours = [wx.RED, wx.WHITE, wx.GREEN, wx.Colour("SKY BLUE")] w, h = dc.GetTextExtent("Hg") x = rect.x + 1 y = rect.y + rect.height/2 - h/2 @@ -347,7 +347,7 @@ class UltimateRenderer_2(object): def GetLineHeight(self): return self.height + 5 - + def GetSubItemWidth(self): @@ -363,13 +363,13 @@ class UltimateRenderer_3(object): lenCDB = len(colourList) colourIndex = random.randint(0, lenCDB-1) self.colour = colourList[colourIndex] - + def DrawSubItem(self, dc, rect, line, highlighted, enabled): centerX, centerY = rect.width/2, rect.height/2 dc.GradientFillConcentric(rect, self.colour, wx.WHITE, (centerX, centerY)) - + def GetLineHeight(self): @@ -379,59 +379,59 @@ class UltimateRenderer_3(object): def GetSubItemWidth(self): return 40 - - + + class UltimateHeaderRenderer(object): def __init__(self, parent): self._hover = False self._pressed = False - + def DrawHeaderButton(self, dc, rect, flags): - + self._hover = False self._pressed = False - + color = wx.Colour(150,150,150) if flags & wx.CONTROL_DISABLED: color = wx.Colour(wx.WHITE) elif flags & wx.CONTROL_SELECTED: color = wx.Colour(wx.BLUE) - + if flags & wx.CONTROL_PRESSED: self._pressed = True color = cutils.AdjustColour(color,-50) elif flags & wx.CONTROL_CURRENT: self._hover = True color = cutils.AdjustColour(color,50) - + dc.SetBrush(wx.Brush(color, wx.SOLID)) dc.SetBackgroundMode(wx.SOLID) dc.SetPen(wx.TRANSPARENT_PEN) - dc.DrawRectangleRect(rect) + dc.DrawRectangle(rect) - dc.SetBackgroundMode(wx.TRANSPARENT) + dc.SetBackgroundMode(wx.TRANSPARENT) def GetForegroundColour(self): - + if self._hover: return wx.Colour(30,30,30) else: return wx.Colour(230,230,230) - - + + class TestUltimateListCtrl(ULC.UltimateListCtrl): - + def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, agwStyle=0): - + ULC.UltimateListCtrl.__init__(self, parent, id, pos, size, style, agwStyle) ## listmix.TextEditMixin.__init__(self) - + class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): - + def __init__(self, parent, log): wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS|wx.SUNKEN_BORDER) @@ -442,7 +442,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): self.colourList = cdb.getColourList() self.count = 0 self.log = log - + self.il = ULC.PyImageList(16, 16) self.idx1 = self.il.Add(images.Smiles.GetBitmap()) @@ -454,7 +454,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): self.il.Add(images.expansion.GetBitmap()) self.il.Add(decryptedBitmap.GetBitmap()) self.il.Add(coloursBitmap.GetBitmap()) - + self.list = TestUltimateListCtrl(self, -1, agwStyle=wx.LC_REPORT #| wx.BORDER_SUNKEN @@ -466,7 +466,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): | wx.LC_HRULES #| wx.LC_SINGLE_SEL | ULC.ULC_HAS_VARIABLE_ROW_HEIGHT) - + self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL) sizer.Add(self.list, 1, wx.EXPAND) @@ -503,25 +503,25 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): self.Bind(wx.EVT_IDLE, self.OnIdle) self.Bind(wx.EVT_TIMER, self.OnTimer) - + def PopulateList(self): self.list.Freeze() - font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) - boldfont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) + boldfont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) boldfont.SetWeight(wx.BOLD) boldfont.SetPointSize(12) boldfont.SetUnderlined(True) - + info = ULC.UltimateListItem() info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT | ULC.ULC_MASK_CHECK info._image = [1, 2] info._format = 0 info._kind = 1 info._text = "Artist\nName" - + self.list.InsertColumnInfo(0, info) info = ULC.UltimateListItem() @@ -530,7 +530,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): info._image = [] info._text = "Title" info._font = boldfont - + self.list.InsertColumnInfo(1, info) info = ULC.UltimateListItem() @@ -546,18 +546,18 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): info._format = 0 info._text = "Custom Renderer" info._colour = wx.RED - + # Add our custom renderer for the header of column 3, we can also use # SetHeaderCustomRenderer to set the renderer for all the columns. klass = UltimateHeaderRenderer(self) - info.SetCustomRenderer(klass) - + info.SetCustomRenderer(klass) + self.list.InsertColumnInfo(3, info) - + # The custom renderer can also be set for all columns on the header and/or footer # self.list.SetHeaderCustomRenderer(klass) - - # We must first have a footer in order to set its custom renderer: + + # We must first have a footer in order to set its custom renderer: # style = self.list.GetAGWWindowStyleFlag() | ULC.ULC_FOOTER # if self.list.GetAGWWindowStyleFlag() != style: # self.list.SetAGWWindowStyleFlag(style) @@ -565,7 +565,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): items = musicdata.items() renderers = {} - + for key, data in items: if key == 3: index = self.list.InsertImageStringItem(sys.maxint, data[0], [3, 4, 7], it_kind=1) @@ -589,7 +589,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): if random.randint(0, 2) == 2: # set some radiobutton-like item on the 3rd column it_kind = 2 - + self.list.SetStringItem(index, 2, data[2], it_kind=it_kind) self.list.SetStringItem(index, 3, data[3]) @@ -605,7 +605,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): else: klass = UltimateRenderer_3() self.list.SetItemCustomRenderer(index, 3, klass) - + self.list.SetItemData(index, key) self.renderers = renderers @@ -618,7 +618,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): item.SetTextColour(wx.BLUE) pyData = datetime.date(2009, 1, 1) item.SetPyData(pyData) - + self.list.SetItem(item) item = self.list.GetItem(4) item.SetTextColour(wx.RED) @@ -647,48 +647,48 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): item = self.list.GetItem(11, 0) textctrl = wx.TextCtrl(self.list, -1, "I Am A Simple\nMultiline wx.TexCtrl", style=wx.TE_MULTILINE) item.SetWindow(textctrl) - self.list.SetItem(item) + self.list.SetItem(item) # Put an item with overflow self.list.SetItemOverFlow(10, 0, True) - + self.currentItem = 0 fontMask = ULC.ULC_MASK_FONTCOLOUR|ULC.ULC_MASK_FONT fullMask = fontMask|ULC.ULC_MASK_BACKCOLOUR - customRow, customCol, colours = [0, 3], [2, 1], [wx.RED, wx.NamedColour("Yellow")] - + customRow, customCol, colours = [0, 3], [2, 1], [wx.RED, wx.Colour("Yellow")] + for row, col, colour in zip(customRow, customCol, colours): item = self.list.GetItem(row, col) item.SetMask(fullMask) item.SetTextColour(wx.GREEN) - font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetWeight(wx.BOLD) item.SetFont(font) item.SetBackgroundColour(colour) self.list.SetItem(item) - standardFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) - italicFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + standardFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) + italicFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) italicFont.SetStyle(wx.FONTSTYLE_ITALIC) - boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) + boldFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) boldFont.SetWeight(wx.BOLD) lenCDB = len(self.colourList) - + for indx in xrange(11, 20): for col in xrange(self.list.GetColumnCount()): result = random.randint(0, 2) colourIndex = random.randint(0, lenCDB-1) - + if result == 0: fnt = standardFont elif result == 1: fnt = boldFont else: fnt = italicFont - + item = self.list.GetItem(indx, col) item.SetMask(fontMask) item.SetFont(fnt) @@ -718,10 +718,10 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): for check in checks: if check.GetValue() == 1: style = style | eval("ULC." + check.GetLabel()) - + if self.list.GetAGWWindowStyleFlag() != style: self.list.SetAGWWindowStyleFlag(style) - + # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py def GetListCtrl(self): @@ -737,8 +737,8 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): for key, renderer in self.renderers.items(): renderer.UpdateValue() self.list.RefreshItem(key) - - + + def OnIdle(self, event): if self.gauge: @@ -762,7 +762,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): y = event.GetY() self.log.write("x, y = %s\n" % str((x, y))) - + item, flags = self.list.HitTest((x, y)) if item != wx.NOT_FOUND and flags & wx.LIST_HITTEST_ONITEM: @@ -837,11 +837,11 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): def OnColEndDrag(self, event): self.log.write("OnColEndDrag\n") - def OnBeginDrag(self, event): + def OnBeginDrag(self, event): self.log.write("OnBeginDrag\n") - - def OnEndDrag(self, event): + + def OnEndDrag(self, event): self.log.write("OnEndDrag\n") def OnDoubleClick(self, event): @@ -902,7 +902,7 @@ class UltimateListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin): self.log.write("Popup three") self.list.ClearAll() wx.CallAfter(self.PopulateList) - + def OnPopupFour(self, event): self.list.DeleteAllItems() @@ -932,21 +932,21 @@ class TestFrame(wx.Frame): self.leftpanel = wx.ScrolledWindow(splitter, -1, style=wx.SUNKEN_BORDER) self.leftpanel.SetScrollRate(20, 20) width = self.PopulateLeftPanel() - + # add the windows to the splitter and split it. splitter.SplitVertically(self.leftpanel, self.ulc, width+5) splitter.SetMinimumPaneSize(width+5) - + sizer = wx.BoxSizer() sizer.Add(splitter, 1, wx.EXPAND) self.SetSizer(sizer) self.SetIcon(images.Mondrian.GetIcon()) self.CenterOnScreen() self.Show() - + def PopulateLeftPanel(self): - + pnl = wx.Panel(self.leftpanel) mainsizer = wx.BoxSizer(wx.VERTICAL) @@ -963,16 +963,16 @@ class TestFrame(wx.Frame): sorted_styles.sort(key=operator.itemgetter(1)) - count = 0 + count = 0 for styleName, styleVal in sorted_styles: if styleName in ["ULC_VIRTUAL", "ULC_TILE", "ULC_LIST", "ULC_ICON", "ULC_SMALL_ICON", "ULC_AUTOARRANGE"]: continue - + if "SORT" in styleName or "ALIGN" in styleName or "VIEWS" in styleName: continue - + if count == 0: tags = wx.ALL else: @@ -980,12 +980,12 @@ class TestFrame(wx.Frame): check = wx.CheckBox(pnl, -1, styleName) stylesizer.Add(check, 0, tags, 3) - + if self.ulc.list.HasAGWFlag(styleVal): check.SetValue(1) else: check.SetValue(0) - + if styleName in ["ULC_HAS_VARIABLE_ROW_HEIGHT", "ULC_REPORT"]: check.SetValue(1) check.Enable(False) @@ -998,7 +998,7 @@ class TestFrame(wx.Frame): self.checknormal = wx.CheckBox(pnl, -1, "Standard Colours") self.checknormal.Bind(wx.EVT_CHECKBOX, self.OnCheckNormal) sizera.Add(self.checknormal, 0, wx.ALL, 3) - + sizerb = wx.BoxSizer(wx.VERTICAL) self.checkgradient = wx.CheckBox(pnl, -1, "Gradient Theme") self.checkgradient.Bind(wx.EVT_CHECKBOX, self.OnCheckGradient) @@ -1028,7 +1028,7 @@ class TestFrame(wx.Frame): self.checkvista = wx.CheckBox(pnl, -1, "Windows Vista Theme") self.checkvista.Bind(wx.EVT_CHECKBOX, self.OnVista) - + themessizer.Add(sizera, 0, wx.EXPAND) themessizer.Add(sizerb, 0, wx.EXPAND) themessizer.Add((0, 5)) @@ -1053,7 +1053,7 @@ class TestFrame(wx.Frame): self.secondcolour.Enable(False) return mainsizer.CalcMin().width + wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X) - + def OnCheckStyle(self, event): @@ -1085,10 +1085,10 @@ class TestFrame(wx.Frame): self.ulc.list.SetGradientStyle(self.radiovertical.GetValue()) self.ulc.list.EnableSelectionVista(False) self.ulc.list.EnableSelectionGradient(True) - + event.Skip() - - + + def OnHorizontal(self, event): self.ulc.list.SetGradientStyle(self.radiovertical.GetValue()) @@ -1103,14 +1103,14 @@ class TestFrame(wx.Frame): def OnFirstColour(self, event): - col1 = event.GetValue() + col1 = event.GetValue() self.ulc.list.SetFirstGradientColour(wx.Colour(col1[0], col1[1], col1[2])) event.Skip() def OnSecondColour(self, event): - col1 = event.GetValue() + col1 = event.GetValue() self.ulc.list.SetSecondGradientColour(wx.Colour(col1[0], col1[1], col1[2])) event.Skip() @@ -1125,7 +1125,7 @@ class TestFrame(wx.Frame): self.checkgradient.SetValue(0) self.ulc.list.EnableSelectionGradient(False) self.ulc.list.EnableSelectionVista(True) - + event.Skip() diff --git a/demo/agw/UltimateVirtualDemo.py b/demo/agw/UltimateVirtualDemo.py index d1ac7d47..85c21081 100644 --- a/demo/agw/UltimateVirtualDemo.py +++ b/demo/agw/UltimateVirtualDemo.py @@ -25,12 +25,12 @@ def GenerateRandomList(imgList): numImages = random.randint(1, 3) listSize = imgList.GetImageCount() - + for i in xrange(numImages): rList.append(random.randint(0, listSize-1)) - return rList - + return rList + class TestUltimateListCtrl(ULC.UltimateListCtrl): @@ -40,7 +40,7 @@ class TestUltimateListCtrl(ULC.UltimateListCtrl): agwStyle=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES|ULC.ULC_SHOW_TOOLTIPS) self.log = log - + self.il = wx.ImageList(16, 16) self.il.Add(images.Smiles.GetBitmap()) self.il.Add(images.core.GetBitmap()) @@ -60,28 +60,28 @@ class TestUltimateListCtrl(ULC.UltimateListCtrl): self.SetColumnToolTip(1,"Second Column Tooltip!") self.SetColumnToolTip(2,"Third Column Tooltip!") - # After setting the column width you can specify that + # After setting the column width you can specify that # this column expands to fill the window. Only one # column may be specified. self.SetColumnWidth(2, ULC.ULC_AUTOSIZE_FILL) self.SetItemCount(1000000) - + self.attr1 = ULC.UltimateListItemAttr() - self.attr1.SetBackgroundColour(wx.NamedColour("yellow")) + self.attr1.SetBackgroundColour(wx.Colour("yellow")) self.attr2 = ULC.UltimateListItemAttr() - self.attr2.SetBackgroundColour(wx.NamedColour("light blue")) + self.attr2.SetBackgroundColour(wx.Colour("light blue")) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected) - self.randomLists = [GenerateRandomList(self.il) for i in xrange(5)] + self.randomLists = [GenerateRandomList(self.il) for i in xrange(5)] def OnItemSelected(self, event): - + self.currentItem = event.m_itemIndex self.log.write("OnItemSelected: %s, %s, %s, %s\n" %(self.currentItem, self.GetItemText(self.currentItem), @@ -93,7 +93,7 @@ class TestUltimateListCtrl(ULC.UltimateListCtrl): self.log.write("OnItemActivated: %s\nTopItem: %s\n" %(self.GetItemText(self.currentItem), self.GetTopItem())) def getColumnText(self, index, col): - + item = self.GetItem(index, col) return item.GetText() @@ -107,10 +107,10 @@ class TestUltimateListCtrl(ULC.UltimateListCtrl): # determine the text, attributes and/or image based # on values from some external data source, but for # this demo we'll just calculate them - + def OnGetItemText(self, item, col): return "Item %d, column %d" % (item, col) - + def OnGetItemToolTip(self, item, col): if item == 0: return "Tooltip: Item %d, column %d" % (item, col) @@ -130,12 +130,12 @@ class TestUltimateListCtrl(ULC.UltimateListCtrl): def OnGetItemColumnImage(self, item, column): return self.randomLists[item%5] - + def OnGetItemImage(self, item): return self.randomLists[item%5] - + def OnGetItemAttr(self, item): if item % 3 == 1: @@ -169,7 +169,7 @@ class TestUltimateListCtrl(ULC.UltimateListCtrl): elif item%3 == 1: return 1 - return 0 + return 0 #--------------------------------------------------------------------------- diff --git a/demo/agw/Windows7Explorer_Contents.py b/demo/agw/Windows7Explorer_Contents.py index 24e88fab..09c9ef12 100644 --- a/demo/agw/Windows7Explorer_Contents.py +++ b/demo/agw/Windows7Explorer_Contents.py @@ -32,7 +32,7 @@ if 'unicode' in wx.PlatformInfo: def FormatFileSize(size): - + for x in ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB']: if size < 1024.0: @@ -49,7 +49,7 @@ class FirstColumnRenderer(object): self.fileName = fileName self.normalFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) - self.normalFont.SetPointSize(self.normalFont.GetPointSize() + 1) + self.normalFont.SetPointSize(self.normalFont.GetPointSize() + 1) self.smallerFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) self.greyColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT) @@ -57,32 +57,32 @@ class FirstColumnRenderer(object): if os.path.isdir(fileName): self.text = fileName bitmap = wx.Bitmap(os.path.join(bitmapDir, "folder.png"), wx.BITMAP_TYPE_PNG) - self.icon = wx.IconFromBitmap(bitmap) + self.icon = wx.Icon(bitmap) self.description = "" return - + self.text = os.path.split(fileName)[1] extension = os.path.splitext(fileName)[1] if not extension: self.text = fileName bitmap = wx.Bitmap(os.path.join(bitmapDir, "empty_icon.png"), wx.BITMAP_TYPE_PNG) - self.icon = wx.IconFromBitmap(bitmap) + self.icon = wx.Icon(bitmap) self.description = "File" return - + fileType = wx.TheMimeTypesManager.GetFileTypeFromExtension(extension) bmp = wx.Bitmap(os.path.join(bitmapDir, "empty_icon.png"), wx.BITMAP_TYPE_PNG) - bmp = wx.IconFromBitmap(bmp) - + bmp = wx.Icon(bmp) + if not fileType: - icon = wx.IconFromLocation(wx.IconLocation(fileName)) + icon = wx.Icon(wx.IconLocation(fileName)) if not icon.IsOk(): self.icon = bmp else: self.icon = icon - + self.description = "%s File"%extension[1:].upper() return @@ -98,7 +98,7 @@ class FirstColumnRenderer(object): icon = None if icon is None: - icon = wx.IconFromLocation(wx.IconLocation(fileName)) + icon = wx.Icon(wx.IconLocation(fileName)) if icon.IsOk(): bmp = icon else: @@ -108,32 +108,32 @@ class FirstColumnRenderer(object): if " -" in command: command = command[0:command.index(" -")] - icon = wx.IconFromLocation(wx.IconLocation(command)) + icon = wx.Icon(wx.IconLocation(command)) if icon.IsOk(): bmp = icon self.icon = bmp self.description = convert(fileType.GetDescription()) - if not self.description: + if not self.description: self.description = "%s File"%extension[1:].upper() - + def DrawSubItem(self, dc, rect, line, highlighted, enabled): """Draw a custom progress bar using double buffering to prevent flicker""" - bmpWidth, bmpHeight = self.icon.GetWidth(), self.icon.GetHeight() + bmpWidth, bmpHeight = self.icon.GetWidth(), self.icon.GetHeight() dc.DrawIcon(self.icon, rect.x+5, rect.y+(rect.height-bmpHeight)/2) dc.SetFont(self.normalFont) - + textWidth, textHeight = dc.GetTextExtent(self.text) dc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNTEXT)) dc.DrawText(self.text, rect.x+bmpWidth+10, rect.y+(rect.height - textHeight)/4) if not self.description: return - + dc.SetFont(self.smallerFont) dummy1, dummy2= dc.GetTextExtent("Type: ") @@ -144,16 +144,16 @@ class FirstColumnRenderer(object): dc.SetTextForeground(wx.BLACK) dc.DrawText(self.description, rect.x+bmpWidth+dummy1+10, rect.y+3*(rect.height - textHeight)/4) - + def GetLineHeight(self): dc = wx.MemoryDC() - dc.SelectObject(wx.EmptyBitmap(100, 20)) + dc.SelectObject(wx.Bitmap(100, 20)) bmpWidth, bmpHeight = self.icon.GetWidth(), self.icon.GetHeight() dc.SetFont(self.normalFont) - + textWidth, textHeight = dc.GetTextExtent(self.text) dc.SetFont(self.smallerFont) @@ -161,14 +161,14 @@ class FirstColumnRenderer(object): textWidth, textHeight = dc.GetTextExtent("Type: " + self.description) dc.SelectObject(wx.NullBitmap) - + return max(2*textHeight, bmpHeight) + 20 - + def GetSubItemWidth(self): return 250 - + class SecondColumnRenderer(object): @@ -191,7 +191,7 @@ class SecondColumnRenderer(object): s = os.path.getsize(fileName) self.size = FormatFileSize(s) - + def DrawSubItem(self, dc, rect, line, highlighted, enabled): """Draw a custom progress bar using double buffering to prevent flicker""" @@ -210,7 +210,7 @@ class SecondColumnRenderer(object): if not self.size: return - + dummy1, dummy2= dc.GetTextExtent("Size: ") dc.SetTextForeground(self.greyColour) @@ -218,23 +218,23 @@ class SecondColumnRenderer(object): dc.SetTextForeground(wx.BLACK) dc.DrawText(self.size, rect.x+dummy1+5, rect.y+3*(rect.height - textHeight)/4) - + def GetLineHeight(self): dc = wx.MemoryDC() - dc.SelectObject(wx.EmptyBitmap(100, 20)) + dc.SelectObject(wx.Bitmap(100, 20)) textWidth, textHeight, d1, d2 = dc.GetFullTextExtent("Date modified: %s"%self.date, self.smallerFont) dc.SelectObject(wx.NullBitmap) return 2*textHeight + 20 - + def GetSubItemWidth(self): dc = wx.MemoryDC() - dc.SelectObject(wx.EmptyBitmap(100, 20)) + dc.SelectObject(wx.Bitmap(100, 20)) textWidth, textHeight, d1, d2 = dc.GetFullTextExtent("Date modified: %s"%self.date, self.smallerFont) @@ -242,10 +242,10 @@ class SecondColumnRenderer(object): dc.SelectObject(wx.NullBitmap) return textWidth+10 - - + + class Windows7Explorer(ULC.UltimateListCtrl): - + def __init__(self, parent, log): ULC.UltimateListCtrl.__init__(self, parent, -1, style=wx.BORDER_THEME, @@ -260,13 +260,13 @@ class Windows7Explorer(ULC.UltimateListCtrl): self.ClearAll() - self.InsertColumn(0, "Column 1") - self.InsertColumn(1, "Column 2") + self.InsertColumn(0, "Column 1") + self.InsertColumn(1, "Column 2") if not path.strip(): path = os.getcwd() - os.chdir(path) + os.chdir(path) files1 = os.listdir(path) files1.sort() @@ -278,13 +278,13 @@ class Windows7Explorer(ULC.UltimateListCtrl): files = sorted(files, key=operator.itemgetter(0, 2)) dummy_log = wx.LogNull() - + for kind, file, lower in files: index = self.InsertStringItem(sys.maxint, "") klass = FirstColumnRenderer(self, file) self.SetItemCustomRenderer(index, 0, klass) - + self.SetStringItem(index, 1, "") klass = SecondColumnRenderer(self, file) self.SetItemCustomRenderer(index, 1, klass) @@ -312,11 +312,11 @@ class TestFrame(wx.Frame): static = wx.StaticText(panel, -1, "Choose a folder to display:") static.SetFont(font) panelSizer.Add(static, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 10) - + dp1 = wx.DirPickerCtrl(panel, path=os.getcwd(), style=wx.DIRP_USE_TEXTCTRL) dp1.SetTextCtrlProportion(2) panelSizer.Add(dp1, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 10) - + # Create the CustomTreeCtrl, using a derived class defined below self.ulc = Windows7Explorer(panel, self.log) @@ -325,7 +325,7 @@ class TestFrame(wx.Frame): self.Bind(wx.EVT_DIRPICKER_CHANGED, self.OnPickDir, dp1) - self.ulc.SetFocus() + self.ulc.SetFocus() self.SetIcon(images.Mondrian.GetIcon()) self.CenterOnScreen() self.Show() @@ -351,7 +351,7 @@ class TestFrame(wx.Frame): self.ulc.DoLayout() wx.EndBusyCursor() - + #--------------------------------------------------------------------------- diff --git a/demo/agw/XLSGrid.py b/demo/agw/XLSGrid.py index caa6a169..58bc02dd 100644 --- a/demo/agw/XLSGrid.py +++ b/demo/agw/XLSGrid.py @@ -13,11 +13,11 @@ _isStandalone = False try: from agw import xlsgrid as XG + dataDir = os.path.join(dirName, "data") _isStandalone = True except ImportError: # if it's not there locally, try the wxPython lib. import wx.lib.agw.xlsgrid as XG - -dataDir = os.path.join(dirName, "data") + dataDir = os.path.join(dirName, "agw", "data") _hasXLRD = True diff --git a/demo/agw/ZoomBar.py b/demo/agw/ZoomBar.py index 1b9fdaf9..b04ec1a7 100644 --- a/demo/agw/ZoomBar.py +++ b/demo/agw/ZoomBar.py @@ -30,10 +30,10 @@ _buttonStatus = {True: "Disable First Button", class TestPanel(wx.Panel): def __init__(self, parent, log): - + self.log = log self.enabled = True - + wx.Panel.__init__(self, parent, -1) self.sizer_1_staticbox = wx.StaticBox(self, -1, "ZoomBar Options") @@ -42,12 +42,12 @@ class TestPanel(wx.Panel): self.colourzoom = csel.ColourSelect(self, colour=wx.Colour(97, 97, 97)) self.buttonSize = masked.NumCtrl(self, value=32, allowNegative=False, min=32, max=72) - + self.centerZoom = wx.CheckBox(self, -1, "Center Zoom") self.showReflections = wx.CheckBox(self, -1, "Show Reflections") self.showLabels = wx.CheckBox(self, -1, "Show Labels") self.enableButton = wx.Button(self, -1, "Disable First Button") - + self.zbp = ZB.ZoomBar(self, -1) standard = glob.glob(bitmapDir + "/*96.png") @@ -56,17 +56,17 @@ class TestPanel(wx.Panel): separatorImage = bitmapDir + "/separator.gif" separatorReflection = bitmapDir + "/separatorFlip.png" count = 0 - + for std, ref in zip(standard, reflections): if random.randint(0, 1) == 1 and count > 0: sep1 = wx.Bitmap(separatorImage, wx.BITMAP_TYPE_GIF) sep2 = wx.Bitmap(separatorReflection, wx.BITMAP_TYPE_PNG) self.zbp.AddSeparator(sep1, sep2) - + bname = os.path.split(std)[1][0:-6] self.zbp.AddButton(wx.Bitmap(std, wx.BITMAP_TYPE_PNG), wx.Bitmap(ref, wx.BITMAP_TYPE_PNG), bname) count += 1 - + self.zbp.ResetSize() self.SetProperties() @@ -77,11 +77,11 @@ class TestPanel(wx.Panel): self.Bind(wx.EVT_CHECKBOX, self.OnShowReflections, self.showReflections) self.Bind(wx.EVT_CHECKBOX, self.OnShowLabels, self.showLabels) self.Bind(wx.EVT_BUTTON, self.OnEnable, self.enableButton) - + self.Bind(masked.EVT_NUM, self.OnButtonSize, self.buttonSize) self.colourzoom.Bind(csel.EVT_COLOURSELECT, self.OnZoomColour) - + self.Bind(ZB.EVT_ZOOMBAR, self.OnZoomBar) @@ -121,7 +121,7 @@ class TestPanel(wx.Panel): sizer_3.Add(self.buttonSize, 0, wx.ALIGN_CENTER_VERTICAL, 0) sizer_2.Add(sizer_3, 0, wx.EXPAND|wx.ALL, 5) - + sizer_2.Add(self.centerZoom, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) sizer_2.Add(self.showReflections, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) sizer_2.Add(self.showLabels, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) @@ -139,27 +139,27 @@ class TestPanel(wx.Panel): def OnZoomBar(self, event): self.log.write("Selected button index and label: %d, %s\n"%(event.GetSelection(), event.GetLabel())) - + def OnZoomFactor(self, event): value = event.GetInt() self.zbp.SetZoomFactor(value) - + event.Skip() def OnZoomColour(self, event): - colour = event.GetValue() + colour = event.GetValue() self.zbp.SetBarColour(colour) - + def OnCenterZoom(self, event): self.zbp.SetCenterZoom(event.IsChecked()) wx.CallAfter(self.ReLayout) - + def OnShowReflections(self, event): @@ -171,7 +171,7 @@ class TestPanel(wx.Panel): else: self.centerZoom.Enable(True) self.zbp.SetShowReflections(False) - + wx.CallAfter(self.ReLayout) @@ -189,8 +189,8 @@ class TestPanel(wx.Panel): obj = event.GetEventObject() obj.SetLabel(_buttonStatus[self.enabled]) obj.Refresh() - - + + def OnButtonSize(self, event): value = event.GetValue() @@ -198,17 +198,17 @@ class TestPanel(wx.Panel): if value < 32 or value > 72: return - + self.zbp.SetButtonSize(value) wx.CallAfter(self.ReLayout) - + def ReLayout(self): self.Layout() self.Refresh() self.Update() - + #---------------------------------------------------------------------- diff --git a/demo/bitmaps/phoenix_title.png b/demo/bitmaps/phoenix_title.png new file mode 100644 index 0000000000000000000000000000000000000000..5bf83d85cfa8f0fea11a236a0eab7d2c91772c9a GIT binary patch literal 5702 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 literal 0 HcmV?d00001 diff --git a/demo/bitmaps/phoenix_top.png b/demo/bitmaps/phoenix_top.png new file mode 100644 index 0000000000000000000000000000000000000000..5faccd0d8eacb4f2fae3bbc46e42ae75fb240bdf GIT binary patch literal 90998 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 z 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 literal 64072 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
pnvo((36NEwhpk@;=hDl{Eb0>e--k2KVX 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 IM6N<$f|+&_=l}o! diff --git a/demo/demo.pyw b/demo/demo.pyw new file mode 100644 index 00000000..99f75a1a --- /dev/null +++ b/demo/demo.pyw @@ -0,0 +1,4 @@ +#!/usr/bin/env python + +import Main +Main.main() diff --git a/demo/run.py b/demo/run.py index 645f0e88..108c7449 100755 --- a/demo/run.py +++ b/demo/run.py @@ -6,7 +6,7 @@ # Author: Robin Dunn # # Created: 6-March-2000 -# RCS-ID: $Id$ +# RCS-ID: $Id: run.py 68888 2011-08-25 18:45:24Z RD $ # Copyright: (c) 2000 by Total Control Software # Licence: wxWindows license #---------------------------------------------------------------------------- @@ -28,8 +28,8 @@ print "wx.version:", wx.version() print "pid:", os.getpid() ##print "executable:", sys.executable; raw_input("Press Enter...") -assertMode = wx.PYAPP_ASSERT_DIALOG -##assertMode = wx.PYAPP_ASSERT_EXCEPTION +assertMode = wx.APP_ASSERT_DIALOG +##assertMode = wx.APP_ASSERT_EXCEPTION #---------------------------------------------------------------------------- @@ -73,7 +73,7 @@ class RunDemoApp(wx.App, wx.lib.mixins.inspection.InspectionMixin): ns['app'] = self ns['module'] = self.demoModule ns['frame'] = frame - + frame.SetMenuBar(menuBar) frame.Show(True) frame.Bind(wx.EVT_CLOSE, self.OnCloseFrame) @@ -117,7 +117,7 @@ class RunDemoApp(wx.App, wx.lib.mixins.inspection.InspectionMixin): shell.Close() evt.Skip() frame.Bind(wx.EVT_CLOSE, CloseShell) - + return True @@ -132,7 +132,7 @@ class RunDemoApp(wx.App, wx.lib.mixins.inspection.InspectionMixin): def OnWidgetInspector(self, evt): wx.lib.inspection.InspectionTool().Show() - + #---------------------------------------------------------------------------- @@ -144,7 +144,7 @@ def main(argv): useShell = True del sys.argv[x] break - + if len(argv) < 2: print "Please specify a demo module name on the command-line" raise SystemExit diff --git a/demo/version.py b/demo/version.py index 120436de..ea7b8ac9 100644 --- a/demo/version.py +++ b/demo/version.py @@ -1,3 +1,3 @@ # This file was generated by setup.py... -VERSION_STRING = '2.9.5.0' +VERSION_STRING = '2.9.5.81-r74150'