wxPython-zombie 3.1.5.8__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wx/__init__.py +22 -0
- wx/__version__.py +9 -0
- wx/_adv.cp313-win_amd64.pyd +0 -0
- wx/_aui.cp313-win_amd64.pyd +0 -0
- wx/_core.cp313-win_amd64.pyd +0 -0
- wx/_dataview.cp313-win_amd64.pyd +0 -0
- wx/_glcanvas.cp313-win_amd64.pyd +0 -0
- wx/_grid.cp313-win_amd64.pyd +0 -0
- wx/_html.cp313-win_amd64.pyd +0 -0
- wx/_html2.cp313-win_amd64.pyd +0 -0
- wx/_media.cp313-win_amd64.pyd +0 -0
- wx/_msw.cp313-win_amd64.pyd +0 -0
- wx/_propgrid.cp313-win_amd64.pyd +0 -0
- wx/_ribbon.cp313-win_amd64.pyd +0 -0
- wx/_richtext.cp313-win_amd64.pyd +0 -0
- wx/_stc.cp313-win_amd64.pyd +0 -0
- wx/_xml.cp313-win_amd64.pyd +0 -0
- wx/_xrc.cp313-win_amd64.pyd +0 -0
- wx/adv.py +124 -0
- wx/adv.pyi +5182 -0
- wx/aui.py +77 -0
- wx/aui.pyi +3655 -0
- wx/core.py +3540 -0
- wx/core.pyi +50592 -0
- wx/dataview.py +173 -0
- wx/dataview.pyi +3491 -0
- wx/demo/AUI_DockingWindowMgr.py +1154 -0
- wx/demo/AUI_MDI.py +117 -0
- wx/demo/AUI_Notebook.py +58 -0
- wx/demo/About.py +75 -0
- wx/demo/AboutBox.py +75 -0
- wx/demo/ActiveXWrapper_Acrobat.py +132 -0
- wx/demo/ActiveXWrapper_IE.py +187 -0
- wx/demo/ActiveX_FlashWindow.py +107 -0
- wx/demo/ActiveX_IEHtmlWindow.py +242 -0
- wx/demo/ActiveX_PDFWindow.py +204 -0
- wx/demo/ActivityIndicator.py +80 -0
- wx/demo/AddPrivateFont.py +116 -0
- wx/demo/AdjustChannels.py +178 -0
- wx/demo/AlphaDrawing.py +77 -0
- wx/demo/AnalogClock.py +144 -0
- wx/demo/AnimationCtrl.py +104 -0
- wx/demo/ArtProvider.py +893 -0
- wx/demo/BannerWindow.py +1 -0
- wx/demo/BitmapButton.py +87 -0
- wx/demo/BitmapComboBox.py +63 -0
- wx/demo/BitmapFromBuffer.py +140 -0
- wx/demo/Button.py +77 -0
- wx/demo/Cairo.py +197 -0
- wx/demo/Cairo_Snippets.py +135 -0
- wx/demo/Calendar.py +660 -0
- wx/demo/CalendarCtrl.py +122 -0
- wx/demo/CheckBox.py +74 -0
- wx/demo/CheckListBox.py +79 -0
- wx/demo/CheckListCtrl.py +99 -0
- wx/demo/Choice.py +55 -0
- wx/demo/Choicebook.py +80 -0
- wx/demo/CollapsibleHeaderCtrl.py +85 -0
- wx/demo/CollapsiblePane.py +126 -0
- wx/demo/ColorPanel.py +19 -0
- wx/demo/ColourDB.py +203 -0
- wx/demo/ColourDialog.py +76 -0
- wx/demo/ColourSelect.py +119 -0
- wx/demo/ComboBox.py +111 -0
- wx/demo/ComboCtrl.py +153 -0
- wx/demo/ComboTreeBox.py +71 -0
- wx/demo/CommandLinkButton.py +50 -0
- wx/demo/ContextHelp.py +112 -0
- wx/demo/Cursor.py +336 -0
- wx/demo/CustomDragAndDrop.py +353 -0
- wx/demo/DVC_CustomRenderer.py +204 -0
- wx/demo/DVC_DataViewModel.py +365 -0
- wx/demo/DVC_IndexListModel.py +257 -0
- wx/demo/DVC_ListCtrl.py +69 -0
- wx/demo/DVC_TreeCtrl.py +76 -0
- wx/demo/DatePickerCtrl.py +68 -0
- wx/demo/DelayedResult.py +239 -0
- wx/demo/Dialog.py +169 -0
- wx/demo/DialogUnits.py +128 -0
- wx/demo/DirDialog.py +58 -0
- wx/demo/DragAndDrop.py +265 -0
- wx/demo/DragImage.py +316 -0
- wx/demo/DragScroller.py +59 -0
- wx/demo/DrawXXXList.py +436 -0
- wx/demo/DynamicSashWindow.py +177 -0
- wx/demo/EditableListBox.py +101 -0
- wx/demo/Editor.py +70 -0
- wx/demo/EventManager.py +291 -0
- wx/demo/ExpandoTextCtrl.py +164 -0
- wx/demo/FancyText.py +83 -0
- wx/demo/FileBrowseButton.py +100 -0
- wx/demo/FileCtrl.py +97 -0
- wx/demo/FileDialog.py +144 -0
- wx/demo/FileHistory.py +140 -0
- wx/demo/FindReplaceDialog.py +123 -0
- wx/demo/FloatCanvas.py +1959 -0
- wx/demo/FontDialog.py +142 -0
- wx/demo/FontEnumerator.py +82 -0
- wx/demo/Frame.py +85 -0
- wx/demo/GLCanvas.py +371 -0
- wx/demo/Gauge.py +66 -0
- wx/demo/GenericButtons.py +185 -0
- wx/demo/GenericCheckBox.py +65 -0
- wx/demo/GenericDirCtrl.py +74 -0
- wx/demo/GetMouseState.py +159 -0
- wx/demo/GraphicsContext.py +236 -0
- wx/demo/GraphicsGradient.py +281 -0
- wx/demo/Grid.py +95 -0
- wx/demo/GridBagSizer.py +170 -0
- wx/demo/GridCustEditor.py +247 -0
- wx/demo/GridCustTable.py +170 -0
- wx/demo/GridDragAndDrop.py +102 -0
- wx/demo/GridDragable.py +206 -0
- wx/demo/GridEnterHandler.py +66 -0
- wx/demo/GridHugeTable.py +89 -0
- wx/demo/GridLabelRenderer.py +114 -0
- wx/demo/GridSimple.py +270 -0
- wx/demo/GridStdEdRend.py +186 -0
- wx/demo/Grid_MegaExample.py +490 -0
- wx/demo/HTML2_WebView.py +183 -0
- wx/demo/HtmlWindow.py +232 -0
- wx/demo/I18N.py +237 -0
- wx/demo/Image.py +338 -0
- wx/demo/ImageAlpha.py +87 -0
- wx/demo/ImageBrowser.py +70 -0
- wx/demo/ImageFromStream.py +49 -0
- wx/demo/Img2PyArtProvider.py +99 -0
- wx/demo/InfoBar.py +127 -0
- wx/demo/IntCtrl.py +343 -0
- wx/demo/ItemsPicker.py +108 -0
- wx/demo/Joystick.py +1083 -0
- wx/demo/KeyEvents.py +428 -0
- wx/demo/LEDNumberCtrl.py +121 -0
- wx/demo/LayoutAnchors.py +258 -0
- wx/demo/LayoutConstraints.py +149 -0
- wx/demo/Layoutf.py +69 -0
- wx/demo/ListBox.py +164 -0
- wx/demo/ListCtrl.py +538 -0
- wx/demo/ListCtrl_edit.py +155 -0
- wx/demo/ListCtrl_virtual.py +145 -0
- wx/demo/Listbook.py +104 -0
- wx/demo/MDIDemo.py +86 -0
- wx/demo/MDISashDemo.py +152 -0
- wx/demo/MDIWindows.py +66 -0
- wx/demo/Main.py +2768 -0
- wx/demo/Mask.py +137 -0
- wx/demo/MaskedEditControls.py +648 -0
- wx/demo/MaskedNumCtrl.py +359 -0
- wx/demo/MediaCtrl.py +190 -0
- wx/demo/Menu.py +322 -0
- wx/demo/MessageDialog.py +54 -0
- wx/demo/MimeTypesManager.py +354 -0
- wx/demo/MiniFrame.py +67 -0
- wx/demo/MouseGestures.py +198 -0
- wx/demo/MultiChoiceDialog.py +59 -0
- wx/demo/MultiSash.py +95 -0
- wx/demo/MultiSplitterWindow.py +168 -0
- wx/demo/MultipleChoiceDialog.py +101 -0
- wx/demo/Notebook.py +134 -0
- wx/demo/NotificationMessage.py +61 -0
- wx/demo/OGL.py +433 -0
- wx/demo/Overlay.py +209 -0
- wx/demo/OwnerDrawnComboBox.py +152 -0
- wx/demo/PDFViewer.py +109 -0
- wx/demo/PageSetupDialog.py +70 -0
- wx/demo/PenAndBrushStyles.py +208 -0
- wx/demo/Pickers.py +120 -0
- wx/demo/PlateButton.py +430 -0
- wx/demo/PopupControl.py +99 -0
- wx/demo/PopupMenu.py +156 -0
- wx/demo/PopupWindow.py +227 -0
- wx/demo/PrintDialog.py +60 -0
- wx/demo/PrintFramework.py +227 -0
- wx/demo/Process.py +168 -0
- wx/demo/ProgressDialog.py +87 -0
- wx/demo/PropertyGrid.py +1045 -0
- wx/demo/PropertySheetDialog.py +231 -0
- wx/demo/PseudoDC.py +350 -0
- wx/demo/PyColourChooser.py +60 -0
- wx/demo/PyCrust.py +21 -0
- wx/demo/PyPlot.py +83 -0
- wx/demo/PyShell.py +22 -0
- wx/demo/PythonEvents.py +109 -0
- wx/demo/README.txt +7 -0
- wx/demo/RadioBox.py +67 -0
- wx/demo/RadioButton.py +127 -0
- wx/demo/RawBitmapAccess.py +208 -0
- wx/demo/RearrangeDialog.py +160 -0
- wx/demo/RendererNative.py +170 -0
- wx/demo/ResizeWidget.py +76 -0
- wx/demo/RichMessageDialog.py +85 -0
- wx/demo/RichTextCtrl.py +732 -0
- wx/demo/RichToolTip.py +145 -0
- wx/demo/SVGImage_Bitmap.py +130 -0
- wx/demo/SVGImage_Render.py +138 -0
- wx/demo/SashWindow.py +151 -0
- wx/demo/ScrolledMessageDialog.py +52 -0
- wx/demo/ScrolledPanel.py +124 -0
- wx/demo/ScrolledWindow.py +260 -0
- wx/demo/SearchCtrl.py +115 -0
- wx/demo/ShapedWindow.py +145 -0
- wx/demo/Simplebook.py +202 -0
- wx/demo/SingleChoiceDialog.py +56 -0
- wx/demo/SizedControls.py +433 -0
- wx/demo/Sizers.py +609 -0
- wx/demo/Slider.py +52 -0
- wx/demo/Sound.py +95 -0
- wx/demo/SpinButton.py +63 -0
- wx/demo/SpinCtrl.py +56 -0
- wx/demo/SpinCtrlDouble.py +42 -0
- wx/demo/SplitTree.py +146 -0
- wx/demo/SplitterWindow.py +62 -0
- wx/demo/StandardPaths.py +113 -0
- wx/demo/StaticBitmap.py +55 -0
- wx/demo/StaticBox.py +62 -0
- wx/demo/StaticText.py +69 -0
- wx/demo/StatusBar.py +144 -0
- wx/demo/StockButtons.py +113 -0
- wx/demo/StyledTextCtrl_1.py +303 -0
- wx/demo/StyledTextCtrl_2.py +410 -0
- wx/demo/SystemSettings.py +333 -0
- wx/demo/TablePrint.py +215 -0
- wx/demo/TestTable.txt +38 -0
- wx/demo/TextCtrl.py +187 -0
- wx/demo/TextEntryDialog.py +57 -0
- wx/demo/Threads.py +258 -0
- wx/demo/Throbber.py +250 -0
- wx/demo/Ticker.py +147 -0
- wx/demo/TimeCtrl.py +240 -0
- wx/demo/TimePickerCtrl.py +60 -0
- wx/demo/Timer.py +275 -0
- wx/demo/ToggleButton.py +54 -0
- wx/demo/ToolBar.py +249 -0
- wx/demo/ToolTip.py +71 -0
- wx/demo/Toolbook.py +111 -0
- wx/demo/TreeCtrl.py +199 -0
- wx/demo/TreeListCtrl.py +121 -0
- wx/demo/TreeMixin.py +269 -0
- wx/demo/Treebook.py +117 -0
- wx/demo/UIActionSimulator.py +151 -0
- wx/demo/URLDragAndDrop.py +130 -0
- wx/demo/Unicode.py +146 -0
- wx/demo/VListBox.py +176 -0
- wx/demo/Validator.py +237 -0
- wx/demo/Wizard.py +248 -0
- wx/demo/WrapSizer.py +115 -0
- wx/demo/XmlResource.py +80 -0
- wx/demo/XmlResourceHandler.py +199 -0
- wx/demo/XmlResourceSubclass.py +119 -0
- wx/demo/__init__.py +9 -0
- wx/demo/agw/AGWInfoBar.py +175 -0
- wx/demo/agw/AUI.py +3058 -0
- wx/demo/agw/AdvancedSplash.py +59 -0
- wx/demo/agw/AquaButton.py +146 -0
- wx/demo/agw/BalloonTip.py +378 -0
- wx/demo/agw/ButtonPanel.py +890 -0
- wx/demo/agw/CubeColourDialog.py +83 -0
- wx/demo/agw/CustomTreeCtrl.py +2167 -0
- wx/demo/agw/Example1 +67 -0
- wx/demo/agw/Example2 +49 -0
- wx/demo/agw/FlatMenu.py +876 -0
- wx/demo/agw/FlatNotebook.py +994 -0
- wx/demo/agw/FloatSpin.py +475 -0
- wx/demo/agw/FoldPanelBar.py +953 -0
- wx/demo/agw/FourWaySplitter.py +300 -0
- wx/demo/agw/GenericMessageDialog.py +207 -0
- wx/demo/agw/GradientButton.py +156 -0
- wx/demo/agw/HyperLinkCtrl.py +144 -0
- wx/demo/agw/HyperTreeList.py +2660 -0
- wx/demo/agw/KnobCtrl.py +186 -0
- wx/demo/agw/LabelBook.py +567 -0
- wx/demo/agw/MacLargeDemo.py +360 -0
- wx/demo/agw/MultiDirDialog.py +117 -0
- wx/demo/agw/PeakMeter.py +194 -0
- wx/demo/agw/PersistentControls.py +589 -0
- wx/demo/agw/PieCtrl.py +206 -0
- wx/demo/agw/PyBusyInfo.py +64 -0
- wx/demo/agw/PyCollapsiblePane.py +308 -0
- wx/demo/agw/PyGauge.py +162 -0
- wx/demo/agw/PyProgress.py +155 -0
- wx/demo/agw/RibbonBar.py +925 -0
- wx/demo/agw/RulerCtrl.py +454 -0
- wx/demo/agw/ScrolledThumbnail.py +128 -0
- wx/demo/agw/ShapedButton.py +603 -0
- wx/demo/agw/ShortcutEditor.py +397 -0
- wx/demo/agw/SpeedMeter.py +668 -0
- wx/demo/agw/SuperToolTip.py +396 -0
- wx/demo/agw/ThumbDemoConfig.py +603 -0
- wx/demo/agw/ThumbnailCtrl.py +149 -0
- wx/demo/agw/ToasterBox.py +410 -0
- wx/demo/agw/UltimateListCtrl.py +80 -0
- wx/demo/agw/UltimateListIconDemo.py +908 -0
- wx/demo/agw/UltimateListListDemo.py +124 -0
- wx/demo/agw/UltimateReportDemo.py +1146 -0
- wx/demo/agw/UltimateVirtualDemo.py +207 -0
- wx/demo/agw/Windows7Explorer_Contents.py +368 -0
- wx/demo/agw/XLSGrid.py +238 -0
- wx/demo/agw/ZoomBar.py +230 -0
- wx/demo/agw/__demo__.py +183 -0
- wx/demo/agw/bitmaps/Explorer96.png +0 -0
- wx/demo/agw/bitmaps/Explorer96Flip40.png +0 -0
- wx/demo/agw/bitmaps/Folder96.png +0 -0
- wx/demo/agw/bitmaps/Folder96Flip40.png +0 -0
- wx/demo/agw/bitmaps/Monitor96.png +0 -0
- wx/demo/agw/bitmaps/Monitor96Flip40.png +0 -0
- wx/demo/agw/bitmaps/Music96.png +0 -0
- wx/demo/agw/bitmaps/Music96Flip40.png +0 -0
- wx/demo/agw/bitmaps/Photo96.png +0 -0
- wx/demo/agw/bitmaps/Photo96Flip40.png +0 -0
- wx/demo/agw/bitmaps/Search96.png +0 -0
- wx/demo/agw/bitmaps/Search96Flip40.png +0 -0
- wx/demo/agw/bitmaps/Wizard96.png +0 -0
- wx/demo/agw/bitmaps/Wizard96Flip40.png +0 -0
- wx/demo/agw/bitmaps/advancedsplash.png +0 -0
- wx/demo/agw/bitmaps/aquabutton.png +0 -0
- wx/demo/agw/bitmaps/aquachecked.ico +0 -0
- wx/demo/agw/bitmaps/aquaflagged.ico +0 -0
- wx/demo/agw/bitmaps/aquanotchecked.ico +0 -0
- wx/demo/agw/bitmaps/aquanotflagged.ico +0 -0
- wx/demo/agw/bitmaps/canada.gif +0 -0
- wx/demo/agw/bitmaps/checked.ico +0 -0
- wx/demo/agw/bitmaps/columns.png +0 -0
- wx/demo/agw/bitmaps/contexthelp-16.png +0 -0
- wx/demo/agw/bitmaps/contexthelp.png +0 -0
- wx/demo/agw/bitmaps/copy.png +0 -0
- wx/demo/agw/bitmaps/cut.png +0 -0
- wx/demo/agw/bitmaps/editcopy.png +0 -0
- wx/demo/agw/bitmaps/editcut.png +0 -0
- wx/demo/agw/bitmaps/editpaste.png +0 -0
- wx/demo/agw/bitmaps/empty_icon.png +0 -0
- wx/demo/agw/bitmaps/exit-16.png +0 -0
- wx/demo/agw/bitmaps/exit.ico +0 -0
- wx/demo/agw/bitmaps/ffwd.png +0 -0
- wx/demo/agw/bitmaps/ffwddisabled.png +0 -0
- wx/demo/agw/bitmaps/field-16.png +0 -0
- wx/demo/agw/bitmaps/filenew.png +0 -0
- wx/demo/agw/bitmaps/fileopen.png +0 -0
- wx/demo/agw/bitmaps/filesave.png +0 -0
- wx/demo/agw/bitmaps/flagged.ico +0 -0
- wx/demo/agw/bitmaps/folder.png +0 -0
- wx/demo/agw/bitmaps/folder_new.png +0 -0
- wx/demo/agw/bitmaps/ghost.png +0 -0
- wx/demo/agw/bitmaps/gradientbutton.png +0 -0
- wx/demo/agw/bitmaps/help-16.png +0 -0
- wx/demo/agw/bitmaps/help.ico +0 -0
- wx/demo/agw/bitmaps/italy.gif +0 -0
- wx/demo/agw/bitmaps/lbadd.png +0 -0
- wx/demo/agw/bitmaps/lbcharge.png +0 -0
- wx/demo/agw/bitmaps/lbdecrypted.png +0 -0
- wx/demo/agw/bitmaps/lbnews.png +0 -0
- wx/demo/agw/bitmaps/lbroll.png +0 -0
- wx/demo/agw/bitmaps/minus1.ico +0 -0
- wx/demo/agw/bitmaps/minus2.ico +0 -0
- wx/demo/agw/bitmaps/minus3.ico +0 -0
- wx/demo/agw/bitmaps/minus4.ico +0 -0
- wx/demo/agw/bitmaps/minus5.ico +0 -0
- wx/demo/agw/bitmaps/month-16.png +0 -0
- wx/demo/agw/bitmaps/new_file.png +0 -0
- wx/demo/agw/bitmaps/new_folder.png +0 -0
- wx/demo/agw/bitmaps/notchecked.ico +0 -0
- wx/demo/agw/bitmaps/notflagged.ico +0 -0
- wx/demo/agw/bitmaps/ok-16.png +0 -0
- wx/demo/agw/bitmaps/open_folder.png +0 -0
- wx/demo/agw/bitmaps/paste.png +0 -0
- wx/demo/agw/bitmaps/pause.png +0 -0
- wx/demo/agw/bitmaps/pausedisabled.png +0 -0
- wx/demo/agw/bitmaps/play.png +0 -0
- wx/demo/agw/bitmaps/playdisabled.png +0 -0
- wx/demo/agw/bitmaps/plus1.ico +0 -0
- wx/demo/agw/bitmaps/plus2.ico +0 -0
- wx/demo/agw/bitmaps/plus3.ico +0 -0
- wx/demo/agw/bitmaps/plus4.ico +0 -0
- wx/demo/agw/bitmaps/plus5.ico +0 -0
- wx/demo/agw/bitmaps/record.png +0 -0
- wx/demo/agw/bitmaps/recorddisabled.png +0 -0
- wx/demo/agw/bitmaps/recording.gif +0 -0
- wx/demo/agw/bitmaps/rewind.png +0 -0
- wx/demo/agw/bitmaps/rewinddisabled.png +0 -0
- wx/demo/agw/bitmaps/round.png +0 -0
- wx/demo/agw/bitmaps/save.png +0 -0
- wx/demo/agw/bitmaps/separator.gif +0 -0
- wx/demo/agw/bitmaps/separatorflip.png +0 -0
- wx/demo/agw/bitmaps/smfuel.ico +0 -0
- wx/demo/agw/bitmaps/smpi.ico +0 -0
- wx/demo/agw/bitmaps/smtemp.ico +0 -0
- wx/demo/agw/bitmaps/stop.png +0 -0
- wx/demo/agw/bitmaps/stopdisabled.png +0 -0
- wx/demo/agw/bitmaps/sttbutton.png +0 -0
- wx/demo/agw/bitmaps/sttfont.png +0 -0
- wx/demo/agw/bitmaps/sttheader.png +0 -0
- wx/demo/agw/bitmaps/stthelp.png +0 -0
- wx/demo/agw/bitmaps/view1.png +0 -0
- wx/demo/agw/bitmaps/view2.png +0 -0
- wx/demo/agw/bitmaps/view_choose.png +0 -0
- wx/demo/agw/bitmaps/view_detailed.png +0 -0
- wx/demo/agw/bitmaps/view_icon.png +0 -0
- wx/demo/agw/bitmaps/view_multicolumn.png +0 -0
- wx/demo/agw/bitmaps/viewmag-16.png +0 -0
- wx/demo/agw/bitmaps/viewmag-m-16.png +0 -0
- wx/demo/agw/bitmaps/viewmag-p-16.png +0 -0
- wx/demo/agw/bitmaps/viewmagfit-16.png +0 -0
- wx/demo/agw/data/Example_1.xls +0 -0
- wx/demo/agw/images.py +6714 -0
- wx/demo/bitmaps/AG00028_.gif +0 -0
- wx/demo/bitmaps/AG00039_.gif +0 -0
- wx/demo/bitmaps/AG00178_.gif +0 -0
- wx/demo/bitmaps/AG00183_.gif +0 -0
- wx/demo/bitmaps/AG00185_.gif +0 -0
- wx/demo/bitmaps/BD13656_.gif +0 -0
- wx/demo/bitmaps/advancedsplash.png +0 -0
- wx/demo/bitmaps/aquabutton.png +0 -0
- wx/demo/bitmaps/aquachecked.ico +0 -0
- wx/demo/bitmaps/aquaflagged.ico +0 -0
- wx/demo/bitmaps/aquanotchecked.ico +0 -0
- wx/demo/bitmaps/aquanotflagged.ico +0 -0
- wx/demo/bitmaps/canada.gif +0 -0
- wx/demo/bitmaps/checked.ico +0 -0
- wx/demo/bitmaps/columns.png +0 -0
- wx/demo/bitmaps/contexthelp-16.png +0 -0
- wx/demo/bitmaps/contexthelp.png +0 -0
- wx/demo/bitmaps/copy.png +0 -0
- wx/demo/bitmaps/cropshot24x20.png +0 -0
- wx/demo/bitmaps/cut.png +0 -0
- wx/demo/bitmaps/editcopy.png +0 -0
- wx/demo/bitmaps/editcut.png +0 -0
- wx/demo/bitmaps/editpaste.png +0 -0
- wx/demo/bitmaps/exit-16.png +0 -0
- wx/demo/bitmaps/exit.ico +0 -0
- wx/demo/bitmaps/ffwd.png +0 -0
- wx/demo/bitmaps/ffwddisabled.png +0 -0
- wx/demo/bitmaps/field-16.png +0 -0
- wx/demo/bitmaps/filenew.png +0 -0
- wx/demo/bitmaps/fileopen.png +0 -0
- wx/demo/bitmaps/filesave.png +0 -0
- wx/demo/bitmaps/flagged.ico +0 -0
- wx/demo/bitmaps/folder_new.png +0 -0
- wx/demo/bitmaps/ghost.png +0 -0
- wx/demo/bitmaps/gradientbutton.png +0 -0
- wx/demo/bitmaps/help-16.png +0 -0
- wx/demo/bitmaps/help.ico +0 -0
- wx/demo/bitmaps/honeycomb300.png +0 -0
- wx/demo/bitmaps/image.bmp +0 -0
- wx/demo/bitmaps/image.gif +0 -0
- wx/demo/bitmaps/image.ico +0 -0
- wx/demo/bitmaps/image.jpg +0 -0
- wx/demo/bitmaps/image.png +0 -0
- wx/demo/bitmaps/image.tif +0 -0
- wx/demo/bitmaps/italy.gif +0 -0
- wx/demo/bitmaps/lbadd.png +0 -0
- wx/demo/bitmaps/lbcharge.png +0 -0
- wx/demo/bitmaps/lbdecrypted.png +0 -0
- wx/demo/bitmaps/lbnews.png +0 -0
- wx/demo/bitmaps/lbroll.png +0 -0
- wx/demo/bitmaps/minus1.ico +0 -0
- wx/demo/bitmaps/minus2.ico +0 -0
- wx/demo/bitmaps/minus3.ico +0 -0
- wx/demo/bitmaps/minus4.ico +0 -0
- wx/demo/bitmaps/minus5.ico +0 -0
- wx/demo/bitmaps/month-16.png +0 -0
- wx/demo/bitmaps/new_file.png +0 -0
- wx/demo/bitmaps/new_folder.png +0 -0
- wx/demo/bitmaps/notchecked.ico +0 -0
- wx/demo/bitmaps/notflagged.ico +0 -0
- wx/demo/bitmaps/ok-16.png +0 -0
- wx/demo/bitmaps/open_folder.png +0 -0
- wx/demo/bitmaps/paste.png +0 -0
- wx/demo/bitmaps/pause.png +0 -0
- wx/demo/bitmaps/pausedisabled.png +0 -0
- wx/demo/bitmaps/phoenix_title.png +0 -0
- wx/demo/bitmaps/phoenix_top.png +0 -0
- wx/demo/bitmaps/play.png +0 -0
- wx/demo/bitmaps/playdisabled.png +0 -0
- wx/demo/bitmaps/plus1.ico +0 -0
- wx/demo/bitmaps/plus2.ico +0 -0
- wx/demo/bitmaps/plus3.ico +0 -0
- wx/demo/bitmaps/plus4.ico +0 -0
- wx/demo/bitmaps/plus5.ico +0 -0
- wx/demo/bitmaps/record.png +0 -0
- wx/demo/bitmaps/recorddisabled.png +0 -0
- wx/demo/bitmaps/rewind.png +0 -0
- wx/demo/bitmaps/rewinddisabled.png +0 -0
- wx/demo/bitmaps/round.png +0 -0
- wx/demo/bitmaps/save.png +0 -0
- wx/demo/bitmaps/smfuel.ico +0 -0
- wx/demo/bitmaps/smpi.ico +0 -0
- wx/demo/bitmaps/smtemp.ico +0 -0
- wx/demo/bitmaps/snakey_render.png +0 -0
- wx/demo/bitmaps/splash.png +0 -0
- wx/demo/bitmaps/stop.png +0 -0
- wx/demo/bitmaps/stopdisabled.png +0 -0
- wx/demo/bitmaps/sttbutton.png +0 -0
- wx/demo/bitmaps/sttfont.png +0 -0
- wx/demo/bitmaps/sttheader.png +0 -0
- wx/demo/bitmaps/stthelp.png +0 -0
- wx/demo/bitmaps/toucan.png +0 -0
- wx/demo/bitmaps/view1.png +0 -0
- wx/demo/bitmaps/view2.png +0 -0
- wx/demo/bitmaps/view_choose.png +0 -0
- wx/demo/bitmaps/view_detailed.png +0 -0
- wx/demo/bitmaps/view_icon.png +0 -0
- wx/demo/bitmaps/view_multicolumn.png +0 -0
- wx/demo/bitmaps/viewmag-16.png +0 -0
- wx/demo/bitmaps/viewmag-m-16.png +0 -0
- wx/demo/bitmaps/viewmag-p-16.png +0 -0
- wx/demo/bitmaps/viewmagfit-16.png +0 -0
- wx/demo/bmp_source/001.png +0 -0
- wx/demo/bmp_source/002.png +0 -0
- wx/demo/bmp_source/003.png +0 -0
- wx/demo/bmp_source/004.png +0 -0
- wx/demo/bmp_source/005.png +0 -0
- wx/demo/bmp_source/006.png +0 -0
- wx/demo/bmp_source/007.png +0 -0
- wx/demo/bmp_source/008.png +0 -0
- wx/demo/bmp_source/009.png +0 -0
- wx/demo/bmp_source/010.png +0 -0
- wx/demo/bmp_source/011.png +0 -0
- wx/demo/bmp_source/012.png +0 -0
- wx/demo/bmp_source/013.png +0 -0
- wx/demo/bmp_source/014.png +0 -0
- wx/demo/bmp_source/015.png +0 -0
- wx/demo/bmp_source/016.png +0 -0
- wx/demo/bmp_source/017.png +0 -0
- wx/demo/bmp_source/018.png +0 -0
- wx/demo/bmp_source/019.png +0 -0
- wx/demo/bmp_source/020.png +0 -0
- wx/demo/bmp_source/021.png +0 -0
- wx/demo/bmp_source/022.png +0 -0
- wx/demo/bmp_source/023.png +0 -0
- wx/demo/bmp_source/024.png +0 -0
- wx/demo/bmp_source/025.png +0 -0
- wx/demo/bmp_source/026.png +0 -0
- wx/demo/bmp_source/027.png +0 -0
- wx/demo/bmp_source/028.png +0 -0
- wx/demo/bmp_source/029.png +0 -0
- wx/demo/bmp_source/030.png +0 -0
- wx/demo/bmp_source/DbDec.bmp +0 -0
- wx/demo/bmp_source/DbInc.bmp +0 -0
- wx/demo/bmp_source/Dec.bmp +0 -0
- wx/demo/bmp_source/FRM_0.png +0 -0
- wx/demo/bmp_source/FRM_1.png +0 -0
- wx/demo/bmp_source/FRM_2.png +0 -0
- wx/demo/bmp_source/FRM_3.png +0 -0
- wx/demo/bmp_source/FRM_4.png +0 -0
- wx/demo/bmp_source/FRM_5.png +0 -0
- wx/demo/bmp_source/FRM_6.png +0 -0
- wx/demo/bmp_source/FRM_7.png +0 -0
- wx/demo/bmp_source/FRM_8.png +0 -0
- wx/demo/bmp_source/GridBG.gif +0 -0
- wx/demo/bmp_source/Inc.bmp +0 -0
- wx/demo/bmp_source/LB01.png +0 -0
- wx/demo/bmp_source/LB02.png +0 -0
- wx/demo/bmp_source/LB03.png +0 -0
- wx/demo/bmp_source/LB04.png +0 -0
- wx/demo/bmp_source/LB05.png +0 -0
- wx/demo/bmp_source/LB06.png +0 -0
- wx/demo/bmp_source/LB07.png +0 -0
- wx/demo/bmp_source/LB08.png +0 -0
- wx/demo/bmp_source/LB09.png +0 -0
- wx/demo/bmp_source/LB10.png +0 -0
- wx/demo/bmp_source/LB11.png +0 -0
- wx/demo/bmp_source/LB12.png +0 -0
- wx/demo/bmp_source/Pt.bmp +0 -0
- wx/demo/bmp_source/Vippi.png +0 -0
- wx/demo/bmp_source/backgrnd.png +0 -0
- wx/demo/bmp_source/book.png +0 -0
- wx/demo/bmp_source/book_blue.png +0 -0
- wx/demo/bmp_source/book_green.png +0 -0
- wx/demo/bmp_source/book_red.png +0 -0
- wx/demo/bmp_source/bp_btn1.png +0 -0
- wx/demo/bmp_source/bp_btn2.png +0 -0
- wx/demo/bmp_source/bp_btn3.png +0 -0
- wx/demo/bmp_source/bp_btn4.png +0 -0
- wx/demo/bmp_source/bulb1.bmp +0 -0
- wx/demo/bmp_source/bulb2.bmp +0 -0
- wx/demo/bmp_source/carrot.png +0 -0
- wx/demo/bmp_source/clipboard.png +0 -0
- wx/demo/bmp_source/code.png +0 -0
- wx/demo/bmp_source/core.png +0 -0
- wx/demo/bmp_source/custom.png +0 -0
- wx/demo/bmp_source/customcontrol.png +0 -0
- wx/demo/bmp_source/deletedocs.png +0 -0
- wx/demo/bmp_source/deleteperspective.png +0 -0
- wx/demo/bmp_source/demo.png +0 -0
- wx/demo/bmp_source/dialog.png +0 -0
- wx/demo/bmp_source/exit.png +0 -0
- wx/demo/bmp_source/expansion.png +0 -0
- wx/demo/bmp_source/find.png +0 -0
- wx/demo/bmp_source/findnext.png +0 -0
- wx/demo/bmp_source/floatcanvas.png +0 -0
- wx/demo/bmp_source/frame.png +0 -0
- wx/demo/bmp_source/images.png +0 -0
- wx/demo/bmp_source/inspect.png +0 -0
- wx/demo/bmp_source/layout.png +0 -0
- wx/demo/bmp_source/logo.png +0 -0
- wx/demo/bmp_source/miscellaneous.png +0 -0
- wx/demo/bmp_source/modifiedexists.png +0 -0
- wx/demo/bmp_source/mondrian.ico +0 -0
- wx/demo/bmp_source/morecontrols.png +0 -0
- wx/demo/bmp_source/moredialog.png +0 -0
- wx/demo/bmp_source/noicon.png +0 -0
- wx/demo/bmp_source/overview.png +0 -0
- wx/demo/bmp_source/pencil.png +0 -0
- wx/demo/bmp_source/pointy.png +0 -0
- wx/demo/bmp_source/process.png +0 -0
- wx/demo/bmp_source/pyshell.png +0 -0
- wx/demo/bmp_source/recent.png +0 -0
- wx/demo/bmp_source/rest.png +0 -0
- wx/demo/bmp_source/robin.jpg +0 -0
- wx/demo/bmp_source/rt_alignleft.xpm +24 -0
- wx/demo/bmp_source/rt_alignright.xpm +24 -0
- wx/demo/bmp_source/rt_bold.xpm +24 -0
- wx/demo/bmp_source/rt_centre.xpm +24 -0
- wx/demo/bmp_source/rt_colour.xpm +59 -0
- wx/demo/bmp_source/rt_copy.xpm +44 -0
- wx/demo/bmp_source/rt_cut.xpm +46 -0
- wx/demo/bmp_source/rt_font.xpm +25 -0
- wx/demo/bmp_source/rt_idea.xpm +47 -0
- wx/demo/bmp_source/rt_indentless.xpm +25 -0
- wx/demo/bmp_source/rt_indentmore.xpm +25 -0
- wx/demo/bmp_source/rt_italic.xpm +25 -0
- wx/demo/bmp_source/rt_open.xpm +57 -0
- wx/demo/bmp_source/rt_paste.xpm +46 -0
- wx/demo/bmp_source/rt_redo.xpm +58 -0
- wx/demo/bmp_source/rt_sample.xpm +44 -0
- wx/demo/bmp_source/rt_save.xpm +42 -0
- wx/demo/bmp_source/rt_smiley.xpm +42 -0
- wx/demo/bmp_source/rt_underline.xpm +25 -0
- wx/demo/bmp_source/rt_undo.xpm +58 -0
- wx/demo/bmp_source/rt_zebra.xpm +409 -0
- wx/demo/bmp_source/saveperspective.png +0 -0
- wx/demo/bmp_source/sm_down.bmp +0 -0
- wx/demo/bmp_source/sm_up.bmp +0 -0
- wx/demo/bmp_source/smiles2.bmp +0 -0
- wx/demo/bmp_source/test2.bmp +0 -0
- wx/demo/bmp_source/testmask.bmp +0 -0
- wx/demo/bmp_source/teststar.png +0 -0
- wx/demo/bmp_source/thekid.png +0 -0
- wx/demo/bmp_source/tog1.bmp +0 -0
- wx/demo/bmp_source/tog2.bmp +0 -0
- wx/demo/bmp_source/wiztest1.bmp +0 -0
- wx/demo/bmp_source/wiztest2.bmp +0 -0
- wx/demo/bmp_source/wxpdemo.ico +0 -0
- wx/demo/cursors/paperairplane_arrow_blue.cur +0 -0
- wx/demo/cursors/paperairplane_arrow_blue_fadeout80.cur +0 -0
- wx/demo/cursors/paperairplane_arrow_colorshift.ani +0 -0
- wx/demo/cursors/paperairplane_arrow_dark.cur +0 -0
- wx/demo/cursors/paperairplane_arrow_grey.cur +0 -0
- wx/demo/cursors/paperairplane_arrow_red.cur +0 -0
- wx/demo/cursors/paperairplane_arrow_white.cur +0 -0
- wx/demo/cursors/paperairplane_arrow_white24.png +0 -0
- wx/demo/data/0-tiger.svg +725 -0
- wx/demo/data/Asteroid_blaster.swf +0 -0
- wx/demo/data/SIL_OPEN_FONT_LICENSE.txt +97 -0
- wx/demo/data/SourceCodePro-Regular.ttf +0 -0
- wx/demo/data/accessories-calculator.svg +636 -0
- wx/demo/data/accessories-text-editor.svg +554 -0
- wx/demo/data/anykey.wav +0 -0
- wx/demo/data/applications-internet.svg +623 -0
- wx/demo/data/desktop-accessibility.svg +245 -0
- wx/demo/data/desktop-keyboard-shortcuts.svg +839 -0
- wx/demo/data/desktop-locale.svg +878 -0
- wx/demo/data/desktop-remote-desktop.svg +1479 -0
- wx/demo/data/desktop-theme.svg +882 -0
- wx/demo/data/desktop-wallpaper.svg +747 -0
- wx/demo/data/echo.py +25 -0
- wx/demo/data/imagemap.htm +20 -0
- wx/demo/data/imagemap.png +0 -0
- wx/demo/data/internet-group-chat.svg +312 -0
- wx/demo/data/internet-mail.svg +440 -0
- wx/demo/data/locale/af/LC_MESSAGES/wxpydemo.mo +0 -0
- wx/demo/data/locale/de/LC_MESSAGES/wxpydemo.mo +0 -0
- wx/demo/data/locale/es/LC_MESSAGES/wxpydemo.mo +0 -0
- wx/demo/data/locale/fr/LC_MESSAGES/wxpydemo.mo +0 -0
- wx/demo/data/locale/it/LC_MESSAGES/wxpydemo.mo +0 -0
- wx/demo/data/locale-src/af.po +23 -0
- wx/demo/data/locale-src/de.po +23 -0
- wx/demo/data/locale-src/es.po +22 -0
- wx/demo/data/locale-src/fr.po +22 -0
- wx/demo/data/locale-src/install +15 -0
- wx/demo/data/locale-src/it.po +23 -0
- wx/demo/data/locale-src/wxpydemo.po +21 -0
- wx/demo/data/office-calendar.svg +316 -0
- wx/demo/data/pic.png +0 -0
- wx/demo/data/pic2.bmp +0 -0
- wx/demo/data/plan.wav +0 -0
- wx/demo/data/proclamation.txt +115 -0
- wx/demo/data/resource.wdr +0 -0
- wx/demo/data/resource_wdr.xrc +146 -0
- wx/demo/data/romedalen.png +0 -0
- wx/demo/data/stc.h.html +3544 -0
- wx/demo/data/system-session.svg +510 -0
- wx/demo/data/system-users.svg +539 -0
- wx/demo/data/tables.htm +116 -0
- wx/demo/data/test-gradient-pen.svg +14 -0
- wx/demo/data/test-opacity.svg +7 -0
- wx/demo/data/test.htm +253 -0
- wx/demo/data/testmovie.mpg +0 -0
- wx/demo/data/testtable.txt +38 -0
- wx/demo/data/tips.txt +73 -0
- wx/demo/data/utilities-system-monitor.svg +435 -0
- wx/demo/data/utilities-terminal.svg +500 -0
- wx/demo/data/widgetTest.htm +70 -0
- wx/demo/data/world.dat +24055 -0
- wx/demo/demo.py +4 -0
- wx/demo/demo.pyw +4 -0
- wx/demo/demodata.py +310 -0
- wx/demo/encode_bitmaps.py +181 -0
- wx/demo/images.py +6812 -0
- wx/demo/infoframe.py +149 -0
- wx/demo/run.py +171 -0
- wx/demo/snippets/__init__.py +13 -0
- wx/demo/snippets/arc.py +21 -0
- wx/demo/snippets/arc_negative.py +21 -0
- wx/demo/snippets/clip.py +13 -0
- wx/demo/snippets/clip_image.py +13 -0
- wx/demo/snippets/curve_rectangle.py +53 -0
- wx/demo/snippets/curve_to.py +17 -0
- wx/demo/snippets/dash.py +18 -0
- wx/demo/snippets/ellipse.py +33 -0
- wx/demo/snippets/fill_and_stroke.py +12 -0
- wx/demo/snippets/fill_and_stroke2.py +18 -0
- wx/demo/snippets/fill_style.py +31 -0
- wx/demo/snippets/glyph_path.py +21 -0
- wx/demo/snippets/gradient.py +16 -0
- wx/demo/snippets/gradient_mask.py +12 -0
- wx/demo/snippets/group.py +16 -0
- wx/demo/snippets/image.py +14 -0
- wx/demo/snippets/imagepattern.py +23 -0
- wx/demo/snippets/path.py +7 -0
- wx/demo/snippets/set_line_cap.py +19 -0
- wx/demo/snippets/set_line_join.py +21 -0
- wx/demo/snippets/show_glyphs.py +15 -0
- wx/demo/snippets/text.py +22 -0
- wx/demo/snippets/text_align_center.py +26 -0
- wx/demo/snippets/text_extents.py +27 -0
- wx/demo/template.py +36 -0
- wx/demo/throbImages.py +1277 -0
- wx/demo/version.py +3 -0
- wx/demo/widgetTest.py +72 -0
- wx/demo/wxpdemo.ico +0 -0
- wx/glcanvas.py +10 -0
- wx/glcanvas.pyi +458 -0
- wx/grid.py +229 -0
- wx/grid.pyi +4959 -0
- wx/html.py +35 -0
- wx/html.pyi +2965 -0
- wx/html2.py +40 -0
- wx/html2.pyi +772 -0
- wx/lib/CDate.py +202 -0
- wx/lib/ClickableHtmlWindow.py +57 -0
- wx/lib/__init__.py +0 -0
- wx/lib/activex.py +178 -0
- wx/lib/activexwrapper.py +153 -0
- wx/lib/agw/__init__.py +128 -0
- wx/lib/agw/advancedsplash.py +564 -0
- wx/lib/agw/aquabutton.py +1127 -0
- wx/lib/agw/artmanager.py +2110 -0
- wx/lib/agw/aui/__init__.py +295 -0
- wx/lib/agw/aui/aui_constants.py +2628 -0
- wx/lib/agw/aui/aui_switcherdialog.py +1227 -0
- wx/lib/agw/aui/aui_utilities.py +672 -0
- wx/lib/agw/aui/auibar.py +4031 -0
- wx/lib/agw/aui/auibook.py +6289 -0
- wx/lib/agw/aui/dockart.py +1198 -0
- wx/lib/agw/aui/framemanager.py +10409 -0
- wx/lib/agw/aui/tabart.py +2771 -0
- wx/lib/agw/aui/tabmdi.py +679 -0
- wx/lib/agw/balloontip.py +1158 -0
- wx/lib/agw/buttonpanel.py +2823 -0
- wx/lib/agw/cubecolourdialog.py +3529 -0
- wx/lib/agw/customtreectrl.py +8963 -0
- wx/lib/agw/data/ShortcutEditor_1.png +0 -0
- wx/lib/agw/data/ShortcutEditor_1_thumb.png +0 -0
- wx/lib/agw/data/ShortcutEditor_2.png +0 -0
- wx/lib/agw/data/ShortcutEditor_2_thumb.png +0 -0
- wx/lib/agw/data/ShortcutEditor_3.png +0 -0
- wx/lib/agw/data/ShortcutEditor_3_thumb.png +0 -0
- wx/lib/agw/data/ShortcutEditor_4.png +0 -0
- wx/lib/agw/data/ShortcutEditor_4_thumb.png +0 -0
- wx/lib/agw/data/default_help_text.html +105 -0
- wx/lib/agw/flatmenu.py +7333 -0
- wx/lib/agw/flatnotebook.py +6672 -0
- wx/lib/agw/floatspin.py +1823 -0
- wx/lib/agw/fmcustomizedlg.py +540 -0
- wx/lib/agw/fmresources.py +407 -0
- wx/lib/agw/foldpanelbar.py +2282 -0
- wx/lib/agw/fourwaysplitter.py +1130 -0
- wx/lib/agw/genericmessagedialog.py +1549 -0
- wx/lib/agw/gradientbutton.py +732 -0
- wx/lib/agw/hyperlink.py +664 -0
- wx/lib/agw/hypertreelist.py +5374 -0
- wx/lib/agw/infobar.py +885 -0
- wx/lib/agw/knobctrl.py +945 -0
- wx/lib/agw/labelbook.py +3029 -0
- wx/lib/agw/multidirdialog.py +615 -0
- wx/lib/agw/peakmeter.py +1029 -0
- wx/lib/agw/persist/__init__.py +188 -0
- wx/lib/agw/persist/persist_constants.py +284 -0
- wx/lib/agw/persist/persist_handlers.py +2614 -0
- wx/lib/agw/persist/persistencemanager.py +864 -0
- wx/lib/agw/piectrl.py +1082 -0
- wx/lib/agw/pybusyinfo.py +399 -0
- wx/lib/agw/pycollapsiblepane.py +940 -0
- wx/lib/agw/pygauge.py +570 -0
- wx/lib/agw/pyprogress.py +917 -0
- wx/lib/agw/ribbon/__init__.py +198 -0
- wx/lib/agw/ribbon/art.py +219 -0
- wx/lib/agw/ribbon/art_aui.py +1284 -0
- wx/lib/agw/ribbon/art_default.py +81 -0
- wx/lib/agw/ribbon/art_internal.py +244 -0
- wx/lib/agw/ribbon/art_msw.py +2736 -0
- wx/lib/agw/ribbon/art_osx.py +52 -0
- wx/lib/agw/ribbon/bar.py +1261 -0
- wx/lib/agw/ribbon/buttonbar.py +1320 -0
- wx/lib/agw/ribbon/control.py +205 -0
- wx/lib/agw/ribbon/gallery.py +974 -0
- wx/lib/agw/ribbon/page.py +946 -0
- wx/lib/agw/ribbon/panel.py +1170 -0
- wx/lib/agw/ribbon/toolbar.py +1442 -0
- wx/lib/agw/rulerctrl.py +1887 -0
- wx/lib/agw/scrolledthumbnail.py +2119 -0
- wx/lib/agw/shapedbutton.py +1809 -0
- wx/lib/agw/shortcuteditor.py +2634 -0
- wx/lib/agw/speedmeter.py +1801 -0
- wx/lib/agw/supertooltip.py +1444 -0
- wx/lib/agw/thumbnailctrl.py +529 -0
- wx/lib/agw/toasterbox.py +1327 -0
- wx/lib/agw/ultimatelistctrl.py +13666 -0
- wx/lib/agw/xlsgrid.py +2113 -0
- wx/lib/agw/zoombar.py +1339 -0
- wx/lib/analogclock/__init__.py +140 -0
- wx/lib/analogclock/analogclock.py +631 -0
- wx/lib/analogclock/helpers.py +991 -0
- wx/lib/analogclock/lib_setup/__init__.py +0 -0
- wx/lib/analogclock/lib_setup/buttontreectrlpanel.py +297 -0
- wx/lib/analogclock/lib_setup/fontselect.py +57 -0
- wx/lib/analogclock/setup.py +490 -0
- wx/lib/analogclock/styles.py +47 -0
- wx/lib/anchors.py +103 -0
- wx/lib/art/__init__.py +4 -0
- wx/lib/art/flagart.py +1583 -0
- wx/lib/art/img2pyartprov.py +56 -0
- wx/lib/busy.py +146 -0
- wx/lib/buttons.py +1141 -0
- wx/lib/calendar.py +1597 -0
- wx/lib/checkbox.py +837 -0
- wx/lib/colourchooser/__init__.py +38 -0
- wx/lib/colourchooser/canvas.py +145 -0
- wx/lib/colourchooser/intl.py +24 -0
- wx/lib/colourchooser/pycolourbox.py +89 -0
- wx/lib/colourchooser/pycolourchooser.py +629 -0
- wx/lib/colourchooser/pycolourslider.py +100 -0
- wx/lib/colourchooser/pypalette.py +211 -0
- wx/lib/colourdb.py +740 -0
- wx/lib/colourselect.py +385 -0
- wx/lib/colourutils.py +118 -0
- wx/lib/combotreebox.py +944 -0
- wx/lib/delayedresult.py +420 -0
- wx/lib/dialogs.py +510 -0
- wx/lib/docview.py +3210 -0
- wx/lib/dragscroller.py +79 -0
- wx/lib/editor/README.txt +77 -0
- wx/lib/editor/__init__.py +24 -0
- wx/lib/editor/editor.py +974 -0
- wx/lib/editor/images.py +15 -0
- wx/lib/editor/selection.py +44 -0
- wx/lib/embeddedimage.py +76 -0
- wx/lib/eventStack.py +136 -0
- wx/lib/eventwatcher.py +440 -0
- wx/lib/evtmgr.py +521 -0
- wx/lib/expando.py +393 -0
- wx/lib/fancytext.py +505 -0
- wx/lib/filebrowsebutton.py +459 -0
- wx/lib/flashwin.py +262 -0
- wx/lib/flashwin_old.py +651 -0
- wx/lib/floatcanvas/FCEvents.py +53 -0
- wx/lib/floatcanvas/FCObjects.py +2923 -0
- wx/lib/floatcanvas/FloatCanvas.py +1027 -0
- wx/lib/floatcanvas/GUIMode.py +396 -0
- wx/lib/floatcanvas/NavCanvas.py +161 -0
- wx/lib/floatcanvas/Resources.py +319 -0
- wx/lib/floatcanvas/ScreenShot.py +1788 -0
- wx/lib/floatcanvas/Utilities/BBox.py +314 -0
- wx/lib/floatcanvas/Utilities/Colors.py +137 -0
- wx/lib/floatcanvas/Utilities/GUI.py +91 -0
- wx/lib/floatcanvas/Utilities/__init__.py +7 -0
- wx/lib/floatcanvas/__init__.py +124 -0
- wx/lib/foldmenu.py +89 -0
- wx/lib/gestures.py +310 -0
- wx/lib/gizmos/__init__.py +18 -0
- wx/lib/gizmos/dynamicsash.py +1202 -0
- wx/lib/gizmos/ledctrl.py +300 -0
- wx/lib/gizmos/treelistctrl.py +87 -0
- wx/lib/graphics.py +1939 -0
- wx/lib/gridmovers.py +511 -0
- wx/lib/iewin.py +249 -0
- wx/lib/iewin_old.py +894 -0
- wx/lib/imagebrowser.py +856 -0
- wx/lib/imageutils.py +163 -0
- wx/lib/infoframe.py +490 -0
- wx/lib/inspection.py +1255 -0
- wx/lib/intctrl.py +1001 -0
- wx/lib/itemspicker.py +256 -0
- wx/lib/langlistctrl.py +480 -0
- wx/lib/layoutf.py +271 -0
- wx/lib/masked/__init__.py +27 -0
- wx/lib/masked/combobox.py +839 -0
- wx/lib/masked/ctrl.py +108 -0
- wx/lib/masked/ipaddrctrl.py +242 -0
- wx/lib/masked/maskededit.py +7279 -0
- wx/lib/masked/numctrl.py +2001 -0
- wx/lib/masked/textctrl.py +465 -0
- wx/lib/masked/timectrl.py +1466 -0
- wx/lib/mixins/__init__.py +17 -0
- wx/lib/mixins/grid.py +47 -0
- wx/lib/mixins/gridlabelrenderer.py +251 -0
- wx/lib/mixins/imagelist.py +77 -0
- wx/lib/mixins/inspection.py +184 -0
- wx/lib/mixins/listctrl.py +894 -0
- wx/lib/mixins/rubberband.py +404 -0
- wx/lib/mixins/treemixin.py +678 -0
- wx/lib/msgpanel.py +95 -0
- wx/lib/multisash.py +747 -0
- wx/lib/myole4ax.idl +178 -0
- wx/lib/myole4ax.tlb +0 -0
- wx/lib/newevent.py +229 -0
- wx/lib/nvdlg.py +156 -0
- wx/lib/ogl/__init__.py +13 -0
- wx/lib/ogl/basic.py +3991 -0
- wx/lib/ogl/bmpshape.py +87 -0
- wx/lib/ogl/canvas.py +467 -0
- wx/lib/ogl/composit.py +1577 -0
- wx/lib/ogl/diagram.py +230 -0
- wx/lib/ogl/divided.py +483 -0
- wx/lib/ogl/drawn.py +900 -0
- wx/lib/ogl/lines.py +1811 -0
- wx/lib/ogl/oglmisc.py +608 -0
- wx/lib/pdfviewer/__init__.py +113 -0
- wx/lib/pdfviewer/bitmaps/ArrowLeft.png +0 -0
- wx/lib/pdfviewer/bitmaps/ArrowRight.png +0 -0
- wx/lib/pdfviewer/bitmaps/DirectionH.png +0 -0
- wx/lib/pdfviewer/bitmaps/DirectionV.png +0 -0
- wx/lib/pdfviewer/bitmaps/PlayerFirst.png +0 -0
- wx/lib/pdfviewer/bitmaps/PlayerLast.png +0 -0
- wx/lib/pdfviewer/bitmaps/PlayerNext.png +0 -0
- wx/lib/pdfviewer/bitmaps/PlayerPrev.png +0 -0
- wx/lib/pdfviewer/bitmaps/Printer.png +0 -0
- wx/lib/pdfviewer/bitmaps/ReadMe.txt +28 -0
- wx/lib/pdfviewer/bitmaps/Save.png +0 -0
- wx/lib/pdfviewer/bitmaps/ZoomIn.png +0 -0
- wx/lib/pdfviewer/bitmaps/ZoomOut.png +0 -0
- wx/lib/pdfviewer/bitmaps/encode_bitmaps.py +37 -0
- wx/lib/pdfviewer/buttonpanel.py +279 -0
- wx/lib/pdfviewer/images.py +240 -0
- wx/lib/pdfviewer/viewer.py +1077 -0
- wx/lib/pdfwin.py +295 -0
- wx/lib/pdfwin_old.py +789 -0
- wx/lib/platebtn.py +789 -0
- wx/lib/plot/CHANGELOG.md +150 -0
- wx/lib/plot/README.md +16 -0
- wx/lib/plot/__init__.py +46 -0
- wx/lib/plot/__main__.py +5 -0
- wx/lib/plot/examples/__init__.py +0 -0
- wx/lib/plot/examples/demo.py +1009 -0
- wx/lib/plot/examples/simple_example.py +54 -0
- wx/lib/plot/plotcanvas.py +2981 -0
- wx/lib/plot/polyobjects.py +1525 -0
- wx/lib/plot/utils.py +327 -0
- wx/lib/popupctl.py +250 -0
- wx/lib/printout.py +1157 -0
- wx/lib/progressindicator.py +151 -0
- wx/lib/pubsub/LICENSE_BSD_Simple.txt +23 -0
- wx/lib/pubsub/README_WxPython.txt +22 -0
- wx/lib/pubsub/RELEASE_NOTES.txt +71 -0
- wx/lib/pubsub/__init__.py +25 -0
- wx/lib/pubsub/core/__init__.py +92 -0
- wx/lib/pubsub/core/arg1/__init__.py +16 -0
- wx/lib/pubsub/core/arg1/listenerimpl.py +97 -0
- wx/lib/pubsub/core/arg1/publisher.py +40 -0
- wx/lib/pubsub/core/arg1/publishermixin.py +34 -0
- wx/lib/pubsub/core/arg1/topicargspecimpl.py +66 -0
- wx/lib/pubsub/core/arg1/topicmgrimpl.py +19 -0
- wx/lib/pubsub/core/callables.py +191 -0
- wx/lib/pubsub/core/imp2.py +63 -0
- wx/lib/pubsub/core/itopicdefnprovider.py +0 -0
- wx/lib/pubsub/core/kwargs/__init__.py +16 -0
- wx/lib/pubsub/core/kwargs/datamsg.py +27 -0
- wx/lib/pubsub/core/kwargs/listenerimpl.py +93 -0
- wx/lib/pubsub/core/kwargs/publisher.py +77 -0
- wx/lib/pubsub/core/kwargs/publishermixin.py +65 -0
- wx/lib/pubsub/core/kwargs/topicargspecimpl.py +217 -0
- wx/lib/pubsub/core/kwargs/topicmgrimpl.py +13 -0
- wx/lib/pubsub/core/listener.py +40 -0
- wx/lib/pubsub/core/listenerbase.py +185 -0
- wx/lib/pubsub/core/notificationmgr.py +185 -0
- wx/lib/pubsub/core/publisherbase.py +191 -0
- wx/lib/pubsub/core/topicargspec.py +77 -0
- wx/lib/pubsub/core/topicdefnprovider.py +632 -0
- wx/lib/pubsub/core/topicexc.py +72 -0
- wx/lib/pubsub/core/topicmgr.py +456 -0
- wx/lib/pubsub/core/topicobj.py +472 -0
- wx/lib/pubsub/core/topictreetraverser.py +143 -0
- wx/lib/pubsub/core/topicutils.py +118 -0
- wx/lib/pubsub/core/treeconfig.py +21 -0
- wx/lib/pubsub/core/validatedefnargs.py +29 -0
- wx/lib/pubsub/core/weakmethod.py +102 -0
- wx/lib/pubsub/policies.py +24 -0
- wx/lib/pubsub/pub.py +199 -0
- wx/lib/pubsub/py2and3.py +608 -0
- wx/lib/pubsub/setuparg1.py +47 -0
- wx/lib/pubsub/setupkwargs.py +29 -0
- wx/lib/pubsub/utils/__init__.py +27 -0
- wx/lib/pubsub/utils/exchandling.py +100 -0
- wx/lib/pubsub/utils/misc.py +100 -0
- wx/lib/pubsub/utils/notification.py +331 -0
- wx/lib/pubsub/utils/topictreeprinter.py +195 -0
- wx/lib/pubsub/utils/xmltopicdefnprovider.py +287 -0
- wx/lib/pydocview.py +3300 -0
- wx/lib/rcsizer.py +229 -0
- wx/lib/resizewidget.py +357 -0
- wx/lib/scrolledpanel.py +225 -0
- wx/lib/sheet.py +350 -0
- wx/lib/sized_controls.py +691 -0
- wx/lib/softwareupdate.py +361 -0
- wx/lib/splitter.py +925 -0
- wx/lib/statbmp.py +199 -0
- wx/lib/stattext.py +322 -0
- wx/lib/throbber.py +425 -0
- wx/lib/ticker.py +295 -0
- wx/lib/ticker_xrc.py +48 -0
- wx/lib/utils.py +89 -0
- wx/lib/wordwrap.py +97 -0
- wx/lib/wxcairo/__init__.py +124 -0
- wx/lib/wxcairo/wx_cairocffi.py +200 -0
- wx/lib/wxcairo/wx_pycairo.py +463 -0
- wx/lib/wxpTag.py +274 -0
- wx/locale/af/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/an/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ar/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ca/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ca@valencia/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/cs/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/da/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/de/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/el/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/es/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/eu/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/fa_IR/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/fi/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/fr/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/gl_ES/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/hi/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/hr/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/hu/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/id/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/it/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ja/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ka/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ko_KR/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/lt/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/lv/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ms/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/nb/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ne/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/nl/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/pl/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/pt/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/pt_BR/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ro/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ru/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sk/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sl/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sq/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sv/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ta/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/tr/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/uk/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/vi/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/zh_CN/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/zh_TW/LC_MESSAGES/wxstd.mo +0 -0
- wx/media.py +27 -0
- wx/media.pyi +223 -0
- wx/msw.py +13 -0
- wx/msw.pyi +65 -0
- wx/propgrid.py +1451 -0
- wx/propgrid.pyi +7914 -0
- wx/py/CHANGES.txt +796 -0
- wx/py/Py.ico +0 -0
- wx/py/PyAlaCarte.py +34 -0
- wx/py/PyAlaMode.py +34 -0
- wx/py/PyAlaModeTest.py +33 -0
- wx/py/PyCrust.ico +0 -0
- wx/py/PyCrust.py +78 -0
- wx/py/PyCrust_16.png +0 -0
- wx/py/PyCrust_32.png +0 -0
- wx/py/PyFilling.py +35 -0
- wx/py/PyShell.py +78 -0
- wx/py/PySlices.ico +0 -0
- wx/py/PySlices.py +98 -0
- wx/py/PySlicesShell.py +94 -0
- wx/py/PySlices_16.png +0 -0
- wx/py/PySlices_32.png +0 -0
- wx/py/PyWrap.py +52 -0
- wx/py/README.txt +77 -0
- wx/py/__init__.py +20 -0
- wx/py/buffer.py +136 -0
- wx/py/crust.py +403 -0
- wx/py/crustslices.py +403 -0
- wx/py/dispatcher.py +259 -0
- wx/py/document.py +37 -0
- wx/py/editor.py +844 -0
- wx/py/editwindow.py +299 -0
- wx/py/filling.py +357 -0
- wx/py/frame.py +978 -0
- wx/py/images.py +212 -0
- wx/py/interpreter.py +170 -0
- wx/py/introspect.py +393 -0
- wx/py/magic.py +98 -0
- wx/py/parse.py +134 -0
- wx/py/path.py +36 -0
- wx/py/pseudo.py +99 -0
- wx/py/shell.py +1588 -0
- wx/py/sliceshell.py +3814 -0
- wx/py/tests/test_interpreter.py +71 -0
- wx/py/tests/test_introspect.py +862 -0
- wx/py/tests/test_pseudo.py +70 -0
- wx/py/tests/test_version.py +36 -0
- wx/py/tests/testall.py +22 -0
- wx/py/version.py +7 -0
- wx/ribbon.py +45 -0
- wx/ribbon.pyi +2494 -0
- wx/richtext.py +142 -0
- wx/richtext.pyi +12113 -0
- wx/siplib.cp313-win_amd64.pyd +0 -0
- wx/stc.py +58 -0
- wx/stc.pyi +8463 -0
- wx/svg/__init__.py +364 -0
- wx/svg/_nanosvg.cp313-win_amd64.pyd +0 -0
- wx/tools/__init__.py +18 -0
- wx/tools/dbg.py +268 -0
- wx/tools/genaxmodule.py +50 -0
- wx/tools/helpviewer.py +92 -0
- wx/tools/img2img.py +85 -0
- wx/tools/img2png.py +54 -0
- wx/tools/img2py.py +309 -0
- wx/tools/img2xpm.py +54 -0
- wx/tools/pywxrc.py +949 -0
- wx/tools/wxget.py +254 -0
- wx/tools/wxget_docs_demo.py +186 -0
- wx/wxbase315u_net_vc140_x64.dll +0 -0
- wx/wxbase315u_vc140_x64.dll +0 -0
- wx/wxbase315u_xml_vc140_x64.dll +0 -0
- wx/wxmsw315u_adv_vc140_x64.dll +0 -0
- wx/wxmsw315u_aui_vc140_x64.dll +0 -0
- wx/wxmsw315u_core_vc140_x64.dll +0 -0
- wx/wxmsw315u_gl_vc140_x64.dll +0 -0
- wx/wxmsw315u_html_vc140_x64.dll +0 -0
- wx/wxmsw315u_media_vc140_x64.dll +0 -0
- wx/wxmsw315u_propgrid_vc140_x64.dll +0 -0
- wx/wxmsw315u_qa_vc140_x64.dll +0 -0
- wx/wxmsw315u_ribbon_vc140_x64.dll +0 -0
- wx/wxmsw315u_richtext_vc140_x64.dll +0 -0
- wx/wxmsw315u_stc_vc140_x64.dll +0 -0
- wx/wxmsw315u_webview_vc140_x64.dll +0 -0
- wx/wxmsw315u_xrc_vc140_x64.dll +0 -0
- wx/xml.py +15 -0
- wx/xml.pyi +575 -0
- wx/xrc.py +65 -0
- wx/xrc.pyi +742 -0
- wxPython_zombie-3.1.5.8.dist-info/LICENSE.txt +950 -0
- wxPython_zombie-3.1.5.8.dist-info/METADATA +107 -0
- wxPython_zombie-3.1.5.8.dist-info/RECORD +1175 -0
- wxPython_zombie-3.1.5.8.dist-info/WHEEL +5 -0
- wxPython_zombie-3.1.5.8.dist-info/entry_points.txt +2 -0
- wxPython_zombie-3.1.5.8.dist-info/top_level.txt +1 -0
wx/lib/ogl/composit.py
ADDED
|
@@ -0,0 +1,1577 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#----------------------------------------------------------------------------
|
|
3
|
+
# Name: composit.py
|
|
4
|
+
# Purpose: Composite class
|
|
5
|
+
#
|
|
6
|
+
# Author: Pierre Hjälm (from C++ original by Julian Smart)
|
|
7
|
+
#
|
|
8
|
+
# Created: 2004-05-08
|
|
9
|
+
# Copyright: (c) 2004 Pierre Hjälm - 1998 Julian Smart
|
|
10
|
+
# Licence: wxWindows license
|
|
11
|
+
# Tags: phoenix-port, unittest, py3-port, documented
|
|
12
|
+
# (c) 2021 Zombie
|
|
13
|
+
#----------------------------------------------------------------------------
|
|
14
|
+
"""
|
|
15
|
+
The :class:`~lib.ogl.composit.CompositeShape` class.
|
|
16
|
+
"""
|
|
17
|
+
import sys
|
|
18
|
+
import wx
|
|
19
|
+
|
|
20
|
+
from .basic import RectangleShape, Shape, ControlPoint
|
|
21
|
+
from .oglmisc import *
|
|
22
|
+
|
|
23
|
+
_objectStartX = 0.0
|
|
24
|
+
_objectStartY = 0.0
|
|
25
|
+
|
|
26
|
+
CONSTRAINT_CENTRED_VERTICALLY = 1
|
|
27
|
+
CONSTRAINT_CENTRED_HORIZONTALLY = 2
|
|
28
|
+
CONSTRAINT_CENTRED_BOTH = 3
|
|
29
|
+
CONSTRAINT_LEFT_OF = 4
|
|
30
|
+
CONSTRAINT_RIGHT_OF = 5
|
|
31
|
+
CONSTRAINT_ABOVE = 6
|
|
32
|
+
CONSTRAINT_BELOW = 7
|
|
33
|
+
CONSTRAINT_ALIGNED_TOP = 8
|
|
34
|
+
CONSTRAINT_ALIGNED_BOTTOM = 9
|
|
35
|
+
CONSTRAINT_ALIGNED_LEFT = 10
|
|
36
|
+
CONSTRAINT_ALIGNED_RIGHT = 11
|
|
37
|
+
|
|
38
|
+
# Like aligned, but with the objects centred on the respective edge
|
|
39
|
+
# of the reference object.
|
|
40
|
+
CONSTRAINT_MIDALIGNED_TOP = 12
|
|
41
|
+
CONSTRAINT_MIDALIGNED_BOTTOM = 13
|
|
42
|
+
CONSTRAINT_MIDALIGNED_LEFT = 14
|
|
43
|
+
CONSTRAINT_MIDALIGNED_RIGHT = 15
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ConstraintType(object):
|
|
47
|
+
"""The :class:`ConstraintType` class."""
|
|
48
|
+
def __init__(self, theType, theName, thePhrase):
|
|
49
|
+
"""
|
|
50
|
+
Default class constructor.
|
|
51
|
+
|
|
52
|
+
:param `theType`: one of the folowing
|
|
53
|
+
====================================== ================================
|
|
54
|
+
Constraint type Description
|
|
55
|
+
====================================== ================================
|
|
56
|
+
`CONSTRAINT_CENTRED_VERTICALLY` Centered vertically
|
|
57
|
+
`CONSTRAINT_CENTRED_HORIZONTALLY` Centered horizontally
|
|
58
|
+
`CONSTRAINT_CENTRED_BOTH` Centered in both directions
|
|
59
|
+
`CONSTRAINT_LEFT_OF` Center left of
|
|
60
|
+
`CONSTRAINT_RIGHT_OF` Center right of
|
|
61
|
+
`CONSTRAINT_ABOVE` Center above
|
|
62
|
+
`CONSTRAINT_BELOW` Center below
|
|
63
|
+
`CONSTRAINT_ALIGNED_TOP` Align top
|
|
64
|
+
`CONSTRAINT_ALIGNED_BOTTOM` Align bottom
|
|
65
|
+
`CONSTRAINT_ALIGNED_LEFT` Align left
|
|
66
|
+
`CONSTRAINT_ALIGNED_RIGHT` Align right
|
|
67
|
+
`CONSTRAINT_MIDALIGNED_TOP` Middle align top
|
|
68
|
+
`CONSTRAINT_MIDALIGNED_BOTTOM` Middle align bottom
|
|
69
|
+
`CONSTRAINT_MIDALIGNED_LEFT` Middle align left
|
|
70
|
+
`CONSTRAINT_MIDALIGNED_RIGHT` Middle align right
|
|
71
|
+
====================================== ================================
|
|
72
|
+
|
|
73
|
+
:param `theName`: the name for the constraint
|
|
74
|
+
:param `thePhrase`: the descriptive phrase
|
|
75
|
+
|
|
76
|
+
"""
|
|
77
|
+
self._type = theType
|
|
78
|
+
self._name = theName
|
|
79
|
+
self._phrase = thePhrase
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
ConstraintTypes = [
|
|
84
|
+
[CONSTRAINT_CENTRED_VERTICALLY,
|
|
85
|
+
ConstraintType(CONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t.")],
|
|
86
|
+
|
|
87
|
+
[CONSTRAINT_CENTRED_HORIZONTALLY,
|
|
88
|
+
ConstraintType(CONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t.")],
|
|
89
|
+
|
|
90
|
+
[CONSTRAINT_CENTRED_BOTH,
|
|
91
|
+
ConstraintType(CONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t.")],
|
|
92
|
+
|
|
93
|
+
[CONSTRAINT_LEFT_OF,
|
|
94
|
+
ConstraintType(CONSTRAINT_LEFT_OF, "Left of", "left of")],
|
|
95
|
+
|
|
96
|
+
[CONSTRAINT_RIGHT_OF,
|
|
97
|
+
ConstraintType(CONSTRAINT_RIGHT_OF, "Right of", "right of")],
|
|
98
|
+
|
|
99
|
+
[CONSTRAINT_ABOVE,
|
|
100
|
+
ConstraintType(CONSTRAINT_ABOVE, "Above", "above")],
|
|
101
|
+
|
|
102
|
+
[CONSTRAINT_BELOW,
|
|
103
|
+
ConstraintType(CONSTRAINT_BELOW, "Below", "below")],
|
|
104
|
+
|
|
105
|
+
# Alignment
|
|
106
|
+
[CONSTRAINT_ALIGNED_TOP,
|
|
107
|
+
ConstraintType(CONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of")],
|
|
108
|
+
|
|
109
|
+
[CONSTRAINT_ALIGNED_BOTTOM,
|
|
110
|
+
ConstraintType(CONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of")],
|
|
111
|
+
|
|
112
|
+
[CONSTRAINT_ALIGNED_LEFT,
|
|
113
|
+
ConstraintType(CONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of")],
|
|
114
|
+
|
|
115
|
+
[CONSTRAINT_ALIGNED_RIGHT,
|
|
116
|
+
ConstraintType(CONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of")],
|
|
117
|
+
|
|
118
|
+
# Mid-alignment
|
|
119
|
+
[CONSTRAINT_MIDALIGNED_TOP,
|
|
120
|
+
ConstraintType(CONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of")],
|
|
121
|
+
|
|
122
|
+
[CONSTRAINT_MIDALIGNED_BOTTOM,
|
|
123
|
+
ConstraintType(CONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of")],
|
|
124
|
+
|
|
125
|
+
[CONSTRAINT_MIDALIGNED_LEFT,
|
|
126
|
+
ConstraintType(CONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of")],
|
|
127
|
+
|
|
128
|
+
[CONSTRAINT_MIDALIGNED_RIGHT,
|
|
129
|
+
ConstraintType(CONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of")]
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class Constraint(object):
|
|
134
|
+
"""
|
|
135
|
+
The :class:`Constraint` class helps specify how child shapes are laid out
|
|
136
|
+
with respect to siblings and parents.
|
|
137
|
+
"""
|
|
138
|
+
def __init__(self, type, constraining, constrained):
|
|
139
|
+
"""
|
|
140
|
+
Default class constructor.
|
|
141
|
+
|
|
142
|
+
:param `type`: see :class:`ConstraintType` for valid types
|
|
143
|
+
:param `constraining`: the constraining :class:`Shape`
|
|
144
|
+
:param `constrained`: the constrained :class:`Shape`
|
|
145
|
+
|
|
146
|
+
"""
|
|
147
|
+
self._xSpacing = 0.0
|
|
148
|
+
self._ySpacing = 0.0
|
|
149
|
+
|
|
150
|
+
self._constraintType = type
|
|
151
|
+
self._constrainingObject = constraining
|
|
152
|
+
|
|
153
|
+
self._constraintId = 0
|
|
154
|
+
self._constraintName = "noname"
|
|
155
|
+
|
|
156
|
+
self._constrainedObjects = constrained[:]
|
|
157
|
+
|
|
158
|
+
def __repr__(self):
|
|
159
|
+
return "<%s.%s>" % (self.__class__.__module__, self.__class__.__name__)
|
|
160
|
+
|
|
161
|
+
def SetSpacing(self, x, y):
|
|
162
|
+
"""
|
|
163
|
+
Sets the horizontal and vertical spacing for the constraint.
|
|
164
|
+
|
|
165
|
+
:param `x`: the x position
|
|
166
|
+
:param `y`: the y position
|
|
167
|
+
|
|
168
|
+
"""
|
|
169
|
+
self._xSpacing = x
|
|
170
|
+
self._ySpacing = y
|
|
171
|
+
|
|
172
|
+
def Equals(self, a, b):
|
|
173
|
+
"""
|
|
174
|
+
Return `True` if a and b are approximately equal (for the purposes
|
|
175
|
+
of evaluating the constraint).
|
|
176
|
+
|
|
177
|
+
:param `a`: ???
|
|
178
|
+
:param `b`: ???
|
|
179
|
+
|
|
180
|
+
"""
|
|
181
|
+
marg = 0.5
|
|
182
|
+
|
|
183
|
+
return b <= a + marg and b >= a - marg
|
|
184
|
+
|
|
185
|
+
def Evaluate(self):
|
|
186
|
+
"""Evaluate this constraint and return `True` if anything changed."""
|
|
187
|
+
maxWidth, maxHeight = self._constrainingObject.GetBoundingBoxMax()
|
|
188
|
+
minWidth, minHeight = self._constrainingObject.GetBoundingBoxMin()
|
|
189
|
+
x = self._constrainingObject.GetX()
|
|
190
|
+
y = self._constrainingObject.GetY()
|
|
191
|
+
|
|
192
|
+
dc = wx.MemoryDC()
|
|
193
|
+
dc.SelectObject(self._constrainingObject.GetCanvas().GetBuffer())
|
|
194
|
+
self._constrainingObject.GetCanvas().PrepareDC(dc)
|
|
195
|
+
|
|
196
|
+
if self._constraintType == CONSTRAINT_CENTRED_VERTICALLY:
|
|
197
|
+
n = len(self._constrainedObjects)
|
|
198
|
+
totalObjectHeight = 0.0
|
|
199
|
+
for constrainedObject in self._constrainedObjects:
|
|
200
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
201
|
+
totalObjectHeight += height2
|
|
202
|
+
|
|
203
|
+
# Check if within the constraining object...
|
|
204
|
+
if totalObjectHeight + (n + 1) * self._ySpacing <= minHeight:
|
|
205
|
+
spacingY = (minHeight - totalObjectHeight) / (n + 1.0)
|
|
206
|
+
startY = y - minHeight / 2.0
|
|
207
|
+
else: # Otherwise, use default spacing
|
|
208
|
+
spacingY = self._ySpacing
|
|
209
|
+
startY = y - (totalObjectHeight + (n + 1) * spacingY) / 2.0
|
|
210
|
+
|
|
211
|
+
# Now position the objects
|
|
212
|
+
changed = False
|
|
213
|
+
for constrainedObject in self._constrainedObjects:
|
|
214
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
215
|
+
startY += spacingY + height2 / 2.0
|
|
216
|
+
if not self.Equals(startY, constrainedObject.GetY()):
|
|
217
|
+
constrainedObject.Move(dc, constrainedObject.GetX(), startY, False)
|
|
218
|
+
changed = True
|
|
219
|
+
startY += height2 / 2.0
|
|
220
|
+
return changed
|
|
221
|
+
elif self._constraintType == CONSTRAINT_CENTRED_HORIZONTALLY:
|
|
222
|
+
n = len(self._constrainedObjects)
|
|
223
|
+
totalObjectWidth = 0.0
|
|
224
|
+
for constrainedObject in self._constrainedObjects:
|
|
225
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
226
|
+
totalObjectWidth += width2
|
|
227
|
+
|
|
228
|
+
# Check if within the constraining object...
|
|
229
|
+
if totalObjectWidth + (n + 1) * self._xSpacing <= minWidth:
|
|
230
|
+
spacingX = (minWidth - totalObjectWidth) / (n + 1.0)
|
|
231
|
+
startX = x - minWidth / 2.0
|
|
232
|
+
else: # Otherwise, use default spacing
|
|
233
|
+
spacingX = self._xSpacing
|
|
234
|
+
startX = x - (totalObjectWidth + (n + 1) * spacingX) / 2.0
|
|
235
|
+
|
|
236
|
+
# Now position the objects
|
|
237
|
+
changed = False
|
|
238
|
+
for constrainedObject in self._constrainedObjects:
|
|
239
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
240
|
+
startX += spacingX + width2 / 2.0
|
|
241
|
+
if not self.Equals(startX, constrainedObject.GetX()):
|
|
242
|
+
constrainedObject.Move(dc, startX, constrainedObject.GetY(), False)
|
|
243
|
+
changed = True
|
|
244
|
+
startX += width2 / 2.0
|
|
245
|
+
return changed
|
|
246
|
+
elif self._constraintType == CONSTRAINT_CENTRED_BOTH:
|
|
247
|
+
n = len(self._constrainedObjects)
|
|
248
|
+
totalObjectWidth = 0.0
|
|
249
|
+
totalObjectHeight = 0.0
|
|
250
|
+
|
|
251
|
+
for constrainedObject in self._constrainedObjects:
|
|
252
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
253
|
+
totalObjectWidth += width2
|
|
254
|
+
totalObjectHeight += height2
|
|
255
|
+
|
|
256
|
+
# Check if within the constraining object...
|
|
257
|
+
if totalObjectHeight + (n + 1) * self._xSpacing <= minWidth:
|
|
258
|
+
spacingX = (minWidth - totalObjectWidth) / (n + 1.0)
|
|
259
|
+
startX = x - minWidth / 2.0
|
|
260
|
+
else: # Otherwise, use default spacing
|
|
261
|
+
spacingX = self._xSpacing
|
|
262
|
+
startX = x - (totalObjectWidth + (n + 1) * spacingX) / 2.0
|
|
263
|
+
|
|
264
|
+
# Check if within the constraining object...
|
|
265
|
+
if totalObjectHeight + (n + 1) * self._ySpacing <= minHeight:
|
|
266
|
+
spacingY = (minHeight - totalObjectHeight) / (n + 1.0)
|
|
267
|
+
startY = y - minHeight / 2.0
|
|
268
|
+
else: # Otherwise, use default spacing
|
|
269
|
+
spacingY = self._ySpacing
|
|
270
|
+
startY = y - (totalObjectHeight + (n + 1) * spacingY) / 2.0
|
|
271
|
+
|
|
272
|
+
# Now position the objects
|
|
273
|
+
changed = False
|
|
274
|
+
for constrainedObject in self._constrainedObjects:
|
|
275
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
276
|
+
startX += spacingX + width2 / 2.0
|
|
277
|
+
startY += spacingY + height2 / 2.0
|
|
278
|
+
|
|
279
|
+
if not self.Equals(startX, constrainedObject.GetX()) or not self.Equals(startY, constrainedObject.GetY()):
|
|
280
|
+
constrainedObject.Move(dc, startX, startY, False)
|
|
281
|
+
changed = True
|
|
282
|
+
|
|
283
|
+
startX += width2 / 2.0
|
|
284
|
+
startY += height2 / 2.0
|
|
285
|
+
return changed
|
|
286
|
+
elif self._constraintType == CONSTRAINT_LEFT_OF:
|
|
287
|
+
changed = False
|
|
288
|
+
for constrainedObject in self._constrainedObjects:
|
|
289
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
290
|
+
|
|
291
|
+
x3 = x - minWidth / 2.0 - width2 / 2.0 - self._xSpacing
|
|
292
|
+
if not self.Equals(x3, constrainedObject.GetX()):
|
|
293
|
+
changed = True
|
|
294
|
+
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
|
|
295
|
+
return changed
|
|
296
|
+
elif self._constraintType == CONSTRAINT_RIGHT_OF:
|
|
297
|
+
changed = False
|
|
298
|
+
|
|
299
|
+
for constrainedObject in self._constrainedObjects:
|
|
300
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
301
|
+
x3 = x + minWidth / 2.0 + width2 / 2.0 + self._xSpacing
|
|
302
|
+
if not self.Equals(x3, constrainedObject.GetX()):
|
|
303
|
+
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
|
|
304
|
+
changed = True
|
|
305
|
+
return changed
|
|
306
|
+
elif self._constraintType == CONSTRAINT_ABOVE:
|
|
307
|
+
changed = False
|
|
308
|
+
|
|
309
|
+
for constrainedObject in self._constrainedObjects:
|
|
310
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
311
|
+
|
|
312
|
+
y3 = y - minHeight / 2.0 - height2 / 2.0 - self._ySpacing
|
|
313
|
+
if not self.Equals(y3, constrainedObject.GetY()):
|
|
314
|
+
changed = True
|
|
315
|
+
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
|
|
316
|
+
return changed
|
|
317
|
+
elif self._constraintType == CONSTRAINT_BELOW:
|
|
318
|
+
changed = False
|
|
319
|
+
|
|
320
|
+
for constrainedObject in self._constrainedObjects:
|
|
321
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
322
|
+
|
|
323
|
+
y3 = y + minHeight / 2.0 + height2 / 2.0 + self._ySpacing
|
|
324
|
+
if not self.Equals(y3, constrainedObject.GetY()):
|
|
325
|
+
changed = True
|
|
326
|
+
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
|
|
327
|
+
return changed
|
|
328
|
+
elif self._constraintType == CONSTRAINT_ALIGNED_LEFT:
|
|
329
|
+
changed = False
|
|
330
|
+
for constrainedObject in self._constrainedObjects:
|
|
331
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
332
|
+
x3 = x - minWidth / 2.0 + width2 / 2.0 + self._xSpacing
|
|
333
|
+
if not self.Equals(x3, constrainedObject.GetX()):
|
|
334
|
+
changed = True
|
|
335
|
+
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
|
|
336
|
+
return changed
|
|
337
|
+
elif self._constraintType == CONSTRAINT_ALIGNED_RIGHT:
|
|
338
|
+
changed = False
|
|
339
|
+
for constrainedObject in self._constrainedObjects:
|
|
340
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
341
|
+
x3 = x + minWidth / 2.0 - width2 / 2.0 - self._xSpacing
|
|
342
|
+
if not self.Equals(x3, constrainedObject.GetX()):
|
|
343
|
+
changed = True
|
|
344
|
+
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
|
|
345
|
+
return changed
|
|
346
|
+
elif self._constraintType == CONSTRAINT_ALIGNED_TOP:
|
|
347
|
+
changed = False
|
|
348
|
+
for constrainedObject in self._constrainedObjects:
|
|
349
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
350
|
+
y3 = y - minHeight / 2.0 + height2 / 2.0 + self._ySpacing
|
|
351
|
+
if not self.Equals(y3, constrainedObject.GetY()):
|
|
352
|
+
changed = True
|
|
353
|
+
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
|
|
354
|
+
return changed
|
|
355
|
+
elif self._constraintType == CONSTRAINT_ALIGNED_BOTTOM:
|
|
356
|
+
changed = False
|
|
357
|
+
for constrainedObject in self._constrainedObjects:
|
|
358
|
+
width2, height2 = constrainedObject.GetBoundingBoxMax()
|
|
359
|
+
y3 = y + minHeight / 2.0 - height2 / 2.0 - self._ySpacing
|
|
360
|
+
if not self.Equals(y3, constrainedObject.GetY()):
|
|
361
|
+
changed = True
|
|
362
|
+
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
|
|
363
|
+
return changed
|
|
364
|
+
elif self._constraintType == CONSTRAINT_MIDALIGNED_LEFT:
|
|
365
|
+
changed = False
|
|
366
|
+
for constrainedObject in self._constrainedObjects:
|
|
367
|
+
x3 = x - minWidth / 2.0
|
|
368
|
+
if not self.Equals(x3, constrainedObject.GetX()):
|
|
369
|
+
changed = True
|
|
370
|
+
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
|
|
371
|
+
return changed
|
|
372
|
+
elif self._constraintType == CONSTRAINT_MIDALIGNED_RIGHT:
|
|
373
|
+
changed = False
|
|
374
|
+
for constrainedObject in self._constrainedObjects:
|
|
375
|
+
x3 = x + minWidth / 2.0
|
|
376
|
+
if not self.Equals(x3, constrainedObject.GetX()):
|
|
377
|
+
changed = True
|
|
378
|
+
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
|
|
379
|
+
return changed
|
|
380
|
+
elif self._constraintType == CONSTRAINT_MIDALIGNED_TOP:
|
|
381
|
+
changed = False
|
|
382
|
+
for constrainedObject in self._constrainedObjects:
|
|
383
|
+
y3 = y - minHeight / 2.0
|
|
384
|
+
if not self.Equals(y3, constrainedObject.GetY()):
|
|
385
|
+
changed = True
|
|
386
|
+
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
|
|
387
|
+
return changed
|
|
388
|
+
elif self._constraintType == CONSTRAINT_MIDALIGNED_BOTTOM:
|
|
389
|
+
changed = False
|
|
390
|
+
for constrainedObject in self._constrainedObjects:
|
|
391
|
+
y3 = y + minHeight / 2.0
|
|
392
|
+
if not self.Equals(y3, constrainedObject.GetY()):
|
|
393
|
+
changed = True
|
|
394
|
+
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
|
|
395
|
+
return changed
|
|
396
|
+
|
|
397
|
+
return False
|
|
398
|
+
|
|
399
|
+
OGLConstraint = wx.deprecated(Constraint,
|
|
400
|
+
"The OGLConstraint name is deprecated, use `ogl.Constraint` instead.")
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
class CompositeShape(RectangleShape):
|
|
404
|
+
"""
|
|
405
|
+
The :class:`CompositeShape` is a shape with a list of child objects, and a
|
|
406
|
+
list of size and positioning constraints between the children.
|
|
407
|
+
"""
|
|
408
|
+
def __init__(self):
|
|
409
|
+
"""
|
|
410
|
+
Default class constructor.
|
|
411
|
+
|
|
412
|
+
"""
|
|
413
|
+
RectangleShape.__init__(self, 100.0, 100.0)
|
|
414
|
+
|
|
415
|
+
self._oldX = self._xpos
|
|
416
|
+
self._oldY = self._ypos
|
|
417
|
+
|
|
418
|
+
self._constraints = []
|
|
419
|
+
self._divisions = [] # In case it's a container
|
|
420
|
+
|
|
421
|
+
def OnDraw(self, dc):
|
|
422
|
+
"""The draw handler."""
|
|
423
|
+
x1 = self._xpos - self._width / 2.0
|
|
424
|
+
y1 = self._ypos - self._height / 2.0
|
|
425
|
+
|
|
426
|
+
if self._shadowMode != SHADOW_NONE:
|
|
427
|
+
if self._shadowBrush:
|
|
428
|
+
dc.SetBrush(self._shadowBrush)
|
|
429
|
+
dc.SetPen(wx.Pen(wx.WHITE, 1, wx.PENSTYLE_TRANSPARENT))
|
|
430
|
+
|
|
431
|
+
if self._cornerRadius:
|
|
432
|
+
dc.DrawRoundedRectangle(x1 + self._shadowOffsetX, y1 + self._shadowOffsetY, self._width, self._height, self._cornerRadius)
|
|
433
|
+
else:
|
|
434
|
+
dc.DrawRectangle(x1 + self._shadowOffsetX, y1 + self._shadowOffsetY, self._width, self._height)
|
|
435
|
+
|
|
436
|
+
# For debug purposes /pi
|
|
437
|
+
#dc.DrawRectangle(x1, y1, self._width, self._height)
|
|
438
|
+
|
|
439
|
+
def OnDrawContents(self, dc):
|
|
440
|
+
"""The draw contents handler."""
|
|
441
|
+
for object in self._children:
|
|
442
|
+
object.Draw(dc)
|
|
443
|
+
object.DrawLinks(dc)
|
|
444
|
+
|
|
445
|
+
Shape.OnDrawContents(self, dc)
|
|
446
|
+
|
|
447
|
+
def OnMovePre(self, dc, x, y, old_x, old_y, display = True):
|
|
448
|
+
"""The move 'pre' handler."""
|
|
449
|
+
diffX = x - old_x
|
|
450
|
+
diffY = y - old_y
|
|
451
|
+
|
|
452
|
+
for object in self._children:
|
|
453
|
+
object.Erase(dc)
|
|
454
|
+
object.Move(dc, object.GetX() + diffX, object.GetY() + diffY, display)
|
|
455
|
+
|
|
456
|
+
return True
|
|
457
|
+
|
|
458
|
+
def OnErase(self, dc):
|
|
459
|
+
"""The erase handler."""
|
|
460
|
+
RectangleShape.OnErase(self, dc)
|
|
461
|
+
for object in self._children:
|
|
462
|
+
object.Erase(dc)
|
|
463
|
+
|
|
464
|
+
def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
|
|
465
|
+
"""The drag left handler."""
|
|
466
|
+
xx, yy = self._canvas.Snap(x, y)
|
|
467
|
+
offsetX = xx - _objectStartX
|
|
468
|
+
offsetY = yy - _objectStartY
|
|
469
|
+
|
|
470
|
+
dc = wx.ClientDC(self.GetCanvas())
|
|
471
|
+
self.GetCanvas().PrepareDC(dc)
|
|
472
|
+
dc.SetLogicalFunction(OGLRBLF)
|
|
473
|
+
|
|
474
|
+
dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
|
|
475
|
+
dc.SetPen(dottedPen)
|
|
476
|
+
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
477
|
+
|
|
478
|
+
self.GetEventHandler().OnDrawOutline(dc, self.GetX() + offsetX, self.GetY() + offsetY, self.GetWidth(), self.GetHeight())
|
|
479
|
+
|
|
480
|
+
def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
481
|
+
"""The begin drag left handler."""
|
|
482
|
+
global _objectStartX, _objectStartY
|
|
483
|
+
|
|
484
|
+
_objectStartX = x
|
|
485
|
+
_objectStartY = y
|
|
486
|
+
|
|
487
|
+
dc = wx.ClientDC(self.GetCanvas())
|
|
488
|
+
self.GetCanvas().PrepareDC(dc)
|
|
489
|
+
dc.SetLogicalFunction(OGLRBLF)
|
|
490
|
+
|
|
491
|
+
dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
|
|
492
|
+
dc.SetPen(dottedPen)
|
|
493
|
+
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
494
|
+
self._canvas.CaptureMouse()
|
|
495
|
+
|
|
496
|
+
xx, yy = self._canvas.Snap(x, y)
|
|
497
|
+
offsetX = xx - _objectStartX
|
|
498
|
+
offsetY = yy - _objectStartY
|
|
499
|
+
|
|
500
|
+
self.GetEventHandler().OnDrawOutline(dc, self.GetX() + offsetX, self.GetY() + offsetY, self.GetWidth(), self.GetHeight())
|
|
501
|
+
|
|
502
|
+
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
503
|
+
"""The end drag left handler."""
|
|
504
|
+
if self._canvas.HasCapture():
|
|
505
|
+
self._canvas.ReleaseMouse()
|
|
506
|
+
|
|
507
|
+
if not self._draggable:
|
|
508
|
+
if self._parent:
|
|
509
|
+
self._parent.GetEventHandler().OnEndDragLeft(x, y, keys, 0)
|
|
510
|
+
return
|
|
511
|
+
|
|
512
|
+
dc = wx.ClientDC(self.GetCanvas())
|
|
513
|
+
self.GetCanvas().PrepareDC(dc)
|
|
514
|
+
dc.SetLogicalFunction(wx.COPY)
|
|
515
|
+
|
|
516
|
+
self.Erase(dc)
|
|
517
|
+
|
|
518
|
+
xx, yy = self._canvas.Snap(x, y)
|
|
519
|
+
offsetX = xx - _objectStartX
|
|
520
|
+
offsetY = yy - _objectStartY
|
|
521
|
+
|
|
522
|
+
self.Move(dc, self.GetX() + offsetX, self.GetY() + offsetY)
|
|
523
|
+
|
|
524
|
+
if self._canvas and not self._canvas.GetQuickEditMode():
|
|
525
|
+
self._canvas.Redraw(dc)
|
|
526
|
+
|
|
527
|
+
def OnRightClick(self, x, y, keys = 0, attachment = 0):
|
|
528
|
+
"""The right click handler.
|
|
529
|
+
|
|
530
|
+
:note: If we get a ctrl-right click, this means send the message to
|
|
531
|
+
the division, so we can invoke a user interface for dealing
|
|
532
|
+
with regions.
|
|
533
|
+
"""
|
|
534
|
+
if keys & KEY_CTRL:
|
|
535
|
+
for division in self._divisions:
|
|
536
|
+
hit = division.HitTest(x, y)
|
|
537
|
+
if hit:
|
|
538
|
+
division.GetEventHandler().OnRightClick(x, y, keys, hit[0])
|
|
539
|
+
break
|
|
540
|
+
|
|
541
|
+
def SetSize(self, w, h, recursive = True):
|
|
542
|
+
"""
|
|
543
|
+
Set the size.
|
|
544
|
+
|
|
545
|
+
:param `w`: the width
|
|
546
|
+
:param `h`: the heigth
|
|
547
|
+
:param `recursive`: size the children recursively
|
|
548
|
+
|
|
549
|
+
"""
|
|
550
|
+
self.SetAttachmentSize(w, h)
|
|
551
|
+
|
|
552
|
+
xScale = float(w) / max(1, self.GetWidth())
|
|
553
|
+
yScale = float(h) / max(1, self.GetHeight())
|
|
554
|
+
|
|
555
|
+
self._width = w
|
|
556
|
+
self._height = h
|
|
557
|
+
|
|
558
|
+
if not recursive:
|
|
559
|
+
return
|
|
560
|
+
|
|
561
|
+
dc = wx.MemoryDC()
|
|
562
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
563
|
+
self.GetCanvas().PrepareDC(dc)
|
|
564
|
+
|
|
565
|
+
for object in self._children:
|
|
566
|
+
# Scale the position first
|
|
567
|
+
newX = (object.GetX() - self.GetX()) * xScale + self.GetX()
|
|
568
|
+
newY = (object.GetY() - self.GetY()) * yScale + self.GetY()
|
|
569
|
+
object.Show(False)
|
|
570
|
+
object.Move(dc, newX, newY)
|
|
571
|
+
object.Show(True)
|
|
572
|
+
|
|
573
|
+
# Now set the scaled size
|
|
574
|
+
xbound, ybound = object.GetBoundingBoxMax()
|
|
575
|
+
if not object.GetFixedWidth():
|
|
576
|
+
xbound *= xScale
|
|
577
|
+
if not object.GetFixedHeight():
|
|
578
|
+
ybound *= yScale
|
|
579
|
+
object.SetSize(xbound, ybound)
|
|
580
|
+
|
|
581
|
+
self.SetDefaultRegionSize()
|
|
582
|
+
|
|
583
|
+
def AddChild(self, child, addAfter = None):
|
|
584
|
+
"""
|
|
585
|
+
Add a shape to the composite. If addAfter is not None, the shape
|
|
586
|
+
will be added after addAfter.
|
|
587
|
+
|
|
588
|
+
:param `child`: an instance of :class:`~lib.ogl.Shape`
|
|
589
|
+
:param `addAfter`: an instance of :class:`~lib.ogl.Shape`
|
|
590
|
+
|
|
591
|
+
"""
|
|
592
|
+
self._children.append(child)
|
|
593
|
+
child.SetParent(self)
|
|
594
|
+
if self._canvas:
|
|
595
|
+
# Ensure we add at the right position
|
|
596
|
+
if addAfter:
|
|
597
|
+
child.RemoveFromCanvas(self._canvas)
|
|
598
|
+
child.AddToCanvas(self._canvas, addAfter)
|
|
599
|
+
|
|
600
|
+
def RemoveChild(self, child):
|
|
601
|
+
"""
|
|
602
|
+
Removes the child from the composite and any constraint
|
|
603
|
+
relationships, but does not delete the child.
|
|
604
|
+
|
|
605
|
+
:param `child`: an instance of :class:`~lib.ogl.Shape`
|
|
606
|
+
|
|
607
|
+
"""
|
|
608
|
+
if child in self._children:
|
|
609
|
+
self._children.remove(child)
|
|
610
|
+
if child in self._divisions:
|
|
611
|
+
self._divisions.remove(child)
|
|
612
|
+
self.RemoveChildFromConstraints(child)
|
|
613
|
+
child.SetParent(None)
|
|
614
|
+
|
|
615
|
+
def Delete(self):
|
|
616
|
+
"""
|
|
617
|
+
Fully disconnect this shape from parents, children, the
|
|
618
|
+
canvas, etc.
|
|
619
|
+
"""
|
|
620
|
+
for child in self.GetChildren():
|
|
621
|
+
self.RemoveChild(child)
|
|
622
|
+
child.Delete()
|
|
623
|
+
RectangleShape.Delete(self)
|
|
624
|
+
self._constraints = []
|
|
625
|
+
self._divisions = []
|
|
626
|
+
|
|
627
|
+
def DeleteConstraintsInvolvingChild(self, child):
|
|
628
|
+
"""
|
|
629
|
+
This function deletes constraints which mention the given child.
|
|
630
|
+
|
|
631
|
+
Used when deleting a child from the composite.
|
|
632
|
+
|
|
633
|
+
:param `child`: an instance of :class:`~lib.ogl.Shape`
|
|
634
|
+
|
|
635
|
+
"""
|
|
636
|
+
for constraint in self._constraints:
|
|
637
|
+
if constraint._constrainingObject == child or child in constraint._constrainedObjects:
|
|
638
|
+
self._constraints.remove(constraint)
|
|
639
|
+
|
|
640
|
+
def RemoveChildFromConstraints(self, child):
|
|
641
|
+
"""
|
|
642
|
+
Removes the child from the constraints.
|
|
643
|
+
|
|
644
|
+
:param `child`: an instance of :class:`~lib.ogl.Shape`
|
|
645
|
+
|
|
646
|
+
"""
|
|
647
|
+
|
|
648
|
+
for constraint in self._constraints:
|
|
649
|
+
if child in constraint._constrainedObjects:
|
|
650
|
+
constraint._constrainedObjects.remove(child)
|
|
651
|
+
if constraint._constrainingObject == child:
|
|
652
|
+
constraint._constrainingObject = None
|
|
653
|
+
|
|
654
|
+
# Delete the constraint if no participants left
|
|
655
|
+
if not constraint._constrainingObject:
|
|
656
|
+
self._constraints.remove(constraint)
|
|
657
|
+
|
|
658
|
+
def AddConstraint(self, constraint):
|
|
659
|
+
"""
|
|
660
|
+
Adds a constraint to the composite.
|
|
661
|
+
|
|
662
|
+
:param `constraint`: an instance of :class:`~lib.ogl.Shape`
|
|
663
|
+
|
|
664
|
+
"""
|
|
665
|
+
self._constraints.append(constraint)
|
|
666
|
+
if constraint._constraintId == 0:
|
|
667
|
+
constraint._constraintId = wx.NewIdRef()
|
|
668
|
+
return constraint
|
|
669
|
+
|
|
670
|
+
def AddSimpleConstraint(self, type, constraining, constrained):
|
|
671
|
+
"""
|
|
672
|
+
Add a constraint of the given type to the composite.
|
|
673
|
+
|
|
674
|
+
:param `type`: see :class:`ConstraintType` for valid types
|
|
675
|
+
:param `constraining`: the constraining :class:`Shape`
|
|
676
|
+
:param `constrained`: the constrained :class:`Shape`
|
|
677
|
+
|
|
678
|
+
"""
|
|
679
|
+
constraint = Constraint(type, constraining, constrained)
|
|
680
|
+
if constraint._constraintId == 0:
|
|
681
|
+
constraint._constraintId = wx.NewIdRef()
|
|
682
|
+
self._constraints.append(constraint)
|
|
683
|
+
return constraint
|
|
684
|
+
|
|
685
|
+
def FindConstraint(self, cId):
|
|
686
|
+
"""
|
|
687
|
+
Finds the constraint with the given id.
|
|
688
|
+
|
|
689
|
+
:param `cId`: The constraint id to find.
|
|
690
|
+
|
|
691
|
+
:returns: None or a tuple of the constraint and the actual composite the
|
|
692
|
+
constraint was in, in case that composite was a descendant of
|
|
693
|
+
this composit.
|
|
694
|
+
|
|
695
|
+
"""
|
|
696
|
+
for constraint in self._constraints:
|
|
697
|
+
if constraint._constraintId == cId:
|
|
698
|
+
return constraint, self
|
|
699
|
+
|
|
700
|
+
# If not found, try children
|
|
701
|
+
for child in self._children:
|
|
702
|
+
if isinstance(child, CompositeShape):
|
|
703
|
+
constraint = child.FindConstraint(cId)
|
|
704
|
+
if constraint:
|
|
705
|
+
return constraint[0], child
|
|
706
|
+
|
|
707
|
+
return None
|
|
708
|
+
|
|
709
|
+
def DeleteConstraint(self, constraint):
|
|
710
|
+
"""
|
|
711
|
+
Deletes constraint from composite.
|
|
712
|
+
|
|
713
|
+
:param `constraint`: the constraint to delete
|
|
714
|
+
|
|
715
|
+
"""
|
|
716
|
+
self._constraints.remove(constraint)
|
|
717
|
+
|
|
718
|
+
def CalculateSize(self):
|
|
719
|
+
"""
|
|
720
|
+
Calculates the size and position of the composite based on
|
|
721
|
+
child sizes and positions.
|
|
722
|
+
|
|
723
|
+
"""
|
|
724
|
+
maxX = -999999.9
|
|
725
|
+
maxY = -999999.9
|
|
726
|
+
minX = 999999.9
|
|
727
|
+
minY = 999999.9
|
|
728
|
+
|
|
729
|
+
for child in self._children:
|
|
730
|
+
# Recalculate size of composite objects because may not conform
|
|
731
|
+
# to size it was set to - depends on the children.
|
|
732
|
+
if isinstance(child, CompositeShape):
|
|
733
|
+
child.CalculateSize()
|
|
734
|
+
|
|
735
|
+
w, h = child.GetBoundingBoxMax()
|
|
736
|
+
if child.GetX() + w / 2.0 > maxX:
|
|
737
|
+
maxX = child.GetX() + w / 2.0
|
|
738
|
+
if child.GetX() - w / 2.0 < minX:
|
|
739
|
+
minX = child.GetX() - w / 2.0
|
|
740
|
+
if child.GetY() + h / 2.0 > maxY:
|
|
741
|
+
maxY = child.GetY() + h / 2.0
|
|
742
|
+
if child.GetY() - h / 2.0 < minY:
|
|
743
|
+
minY = child.GetY() - h / 2.0
|
|
744
|
+
|
|
745
|
+
self._width = maxX - minX
|
|
746
|
+
self._height = maxY - minY
|
|
747
|
+
self._xpos = self._width / 2.0 + minX
|
|
748
|
+
self._ypos = self._height / 2.0 + minY
|
|
749
|
+
|
|
750
|
+
def Recompute(self):
|
|
751
|
+
"""
|
|
752
|
+
Recomputes any constraints associated with the object. If `False` is
|
|
753
|
+
returned, the constraints could not be satisfied (there was an
|
|
754
|
+
inconsistency).
|
|
755
|
+
|
|
756
|
+
"""
|
|
757
|
+
noIterations = 0
|
|
758
|
+
changed = True
|
|
759
|
+
while changed and noIterations < 500:
|
|
760
|
+
changed = self.Constrain()
|
|
761
|
+
noIterations += 1
|
|
762
|
+
|
|
763
|
+
return not changed
|
|
764
|
+
|
|
765
|
+
def Constrain(self):
|
|
766
|
+
"""
|
|
767
|
+
Constrain the children.
|
|
768
|
+
|
|
769
|
+
:returns: True if constained otherwise False
|
|
770
|
+
|
|
771
|
+
"""
|
|
772
|
+
self.CalculateSize()
|
|
773
|
+
|
|
774
|
+
changed = False
|
|
775
|
+
for child in self._children:
|
|
776
|
+
if isinstance(child, CompositeShape) and child.Constrain():
|
|
777
|
+
changed = True
|
|
778
|
+
|
|
779
|
+
for constraint in self._constraints:
|
|
780
|
+
if constraint.Evaluate():
|
|
781
|
+
changed = True
|
|
782
|
+
|
|
783
|
+
return changed
|
|
784
|
+
|
|
785
|
+
def MakeContainer(self):
|
|
786
|
+
"""
|
|
787
|
+
Makes this composite into a container by creating one child
|
|
788
|
+
DivisionShape.
|
|
789
|
+
"""
|
|
790
|
+
division = self.OnCreateDivision()
|
|
791
|
+
self._divisions.append(division)
|
|
792
|
+
self.AddChild(division)
|
|
793
|
+
|
|
794
|
+
division.SetSize(self._width, self._height)
|
|
795
|
+
|
|
796
|
+
dc = wx.MemoryDC()
|
|
797
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
798
|
+
self.GetCanvas().PrepareDC(dc)
|
|
799
|
+
|
|
800
|
+
division.Move(dc, self.GetX(), self.GetY())
|
|
801
|
+
self.Recompute()
|
|
802
|
+
division.Show(True)
|
|
803
|
+
|
|
804
|
+
def OnCreateDivision(self):
|
|
805
|
+
"""Create division handler."""
|
|
806
|
+
return DivisionShape()
|
|
807
|
+
|
|
808
|
+
def FindContainerImage(self):
|
|
809
|
+
"""
|
|
810
|
+
Finds the image used to visualize a container. This is any child of
|
|
811
|
+
the composite that is not in the divisions list.
|
|
812
|
+
|
|
813
|
+
"""
|
|
814
|
+
for child in self._children:
|
|
815
|
+
if child in self._divisions:
|
|
816
|
+
return child
|
|
817
|
+
|
|
818
|
+
return None
|
|
819
|
+
|
|
820
|
+
def ContainsDivision(self, division):
|
|
821
|
+
"""
|
|
822
|
+
Check if division is descendant.
|
|
823
|
+
|
|
824
|
+
:param `division`: divison to check
|
|
825
|
+
:returns: `True` if division is a descendant of this container.
|
|
826
|
+
|
|
827
|
+
"""
|
|
828
|
+
if division in self._divisions:
|
|
829
|
+
return True
|
|
830
|
+
|
|
831
|
+
for child in self._children:
|
|
832
|
+
if isinstance(child, CompositeShape):
|
|
833
|
+
return child.ContainsDivision(division)
|
|
834
|
+
|
|
835
|
+
return False
|
|
836
|
+
|
|
837
|
+
def GetDivisions(self):
|
|
838
|
+
"""Return the list of divisions."""
|
|
839
|
+
return self._divisions
|
|
840
|
+
|
|
841
|
+
def GetConstraints(self):
|
|
842
|
+
"""Return the list of constraints."""
|
|
843
|
+
return self._constraints
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
DIVISION_SIDE_NONE =0
|
|
847
|
+
DIVISION_SIDE_LEFT =1
|
|
848
|
+
DIVISION_SIDE_TOP =2
|
|
849
|
+
DIVISION_SIDE_RIGHT =3
|
|
850
|
+
DIVISION_SIDE_BOTTOM =4
|
|
851
|
+
|
|
852
|
+
originalX = 0.0
|
|
853
|
+
originalY = 0.0
|
|
854
|
+
originalW = 0.0
|
|
855
|
+
originalH = 0.0
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
class DivisionControlPoint(ControlPoint):
|
|
860
|
+
def __init__(self, the_canvas, object, size, the_xoffset, the_yoffset, the_type):
|
|
861
|
+
ControlPoint.__init__(self, the_canvas, object, size, the_xoffset, the_yoffset, the_type)
|
|
862
|
+
self.SetEraseObject(False)
|
|
863
|
+
|
|
864
|
+
# Implement resizing of canvas object
|
|
865
|
+
def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
|
|
866
|
+
ControlPoint.OnDragLeft(self, draw, x, y, keys, attachment)
|
|
867
|
+
|
|
868
|
+
def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
869
|
+
global originalX, originalY, originalW, originalH
|
|
870
|
+
|
|
871
|
+
originalX = self._shape.GetX()
|
|
872
|
+
originalY = self._shape.GetY()
|
|
873
|
+
originalW = self._shape.GetWidth()
|
|
874
|
+
originalH = self._shape.GetHeight()
|
|
875
|
+
|
|
876
|
+
ControlPoint.OnBeginDragLeft(self, x, y, keys, attachment)
|
|
877
|
+
|
|
878
|
+
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
879
|
+
ControlPoint.OnEndDragLeft(self, x, y, keys, attachment)
|
|
880
|
+
|
|
881
|
+
dc = wx.MemoryDC()
|
|
882
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
883
|
+
self.GetCanvas().PrepareDC(dc)
|
|
884
|
+
|
|
885
|
+
division = self._shape
|
|
886
|
+
divisionParent = division.GetParent()
|
|
887
|
+
|
|
888
|
+
# Need to check it's within the bounds of the parent composite
|
|
889
|
+
x1 = divisionParent.GetX() - divisionParent.GetWidth() / 2.0
|
|
890
|
+
y1 = divisionParent.GetY() - divisionParent.GetHeight() / 2.0
|
|
891
|
+
x2 = divisionParent.GetX() + divisionParent.GetWidth() / 2.0
|
|
892
|
+
y2 = divisionParent.GetY() + divisionParent.GetHeight() / 2.0
|
|
893
|
+
|
|
894
|
+
# Need to check it has not made the division zero or negative
|
|
895
|
+
# width / height
|
|
896
|
+
dx1 = division.GetX() - division.GetWidth() / 2.0
|
|
897
|
+
dy1 = division.GetY() - division.GetHeight() / 2.0
|
|
898
|
+
dx2 = division.GetX() + division.GetWidth() / 2.0
|
|
899
|
+
dy2 = division.GetY() + division.GetHeight() / 2.0
|
|
900
|
+
|
|
901
|
+
success = True
|
|
902
|
+
if division.GetHandleSide() == DIVISION_SIDE_LEFT:
|
|
903
|
+
if x <= x1 or x >= x2 or x >= dx2:
|
|
904
|
+
success = False
|
|
905
|
+
# Try it out first...
|
|
906
|
+
elif not division.ResizeAdjoining(DIVISION_SIDE_LEFT, x, True):
|
|
907
|
+
success = False
|
|
908
|
+
else:
|
|
909
|
+
division.ResizeAdjoining(DIVISION_SIDE_LEFT, x, False)
|
|
910
|
+
elif division.GetHandleSide() == DIVISION_SIDE_TOP:
|
|
911
|
+
if y <= y1 or y >= y2 or y >= dy2:
|
|
912
|
+
success = False
|
|
913
|
+
elif not division.ResizeAdjoining(DIVISION_SIDE_TOP, y, True):
|
|
914
|
+
success = False
|
|
915
|
+
else:
|
|
916
|
+
division.ResizingAdjoining(DIVISION_SIDE_TOP, y, False)
|
|
917
|
+
elif division.GetHandleSide() == DIVISION_SIDE_RIGHT:
|
|
918
|
+
if x <= x1 or x >= x2 or x <= dx1:
|
|
919
|
+
success = False
|
|
920
|
+
elif not division.ResizeAdjoining(DIVISION_SIDE_RIGHT, x, True):
|
|
921
|
+
success = False
|
|
922
|
+
else:
|
|
923
|
+
division.ResizeAdjoining(DIVISION_SIDE_RIGHT, x, False)
|
|
924
|
+
elif division.GetHandleSide() == DIVISION_SIDE_BOTTOM:
|
|
925
|
+
if y <= y1 or y >= y2 or y <= dy1:
|
|
926
|
+
success = False
|
|
927
|
+
elif not division.ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, True):
|
|
928
|
+
success = False
|
|
929
|
+
else:
|
|
930
|
+
division.ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, False)
|
|
931
|
+
|
|
932
|
+
if not success:
|
|
933
|
+
division.SetSize(originalW, originalH)
|
|
934
|
+
division.Move(dc, originalX, originalY)
|
|
935
|
+
|
|
936
|
+
divisionParent.Draw(dc)
|
|
937
|
+
division.GetEventHandler().OnDrawControlPoints(dc)
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
DIVISION_MENU_SPLIT_HORIZONTALLY =1
|
|
942
|
+
DIVISION_MENU_SPLIT_VERTICALLY =2
|
|
943
|
+
DIVISION_MENU_EDIT_LEFT_EDGE =3
|
|
944
|
+
DIVISION_MENU_EDIT_TOP_EDGE =4
|
|
945
|
+
DIVISION_MENU_EDIT_RIGHT_EDGE =5
|
|
946
|
+
DIVISION_MENU_EDIT_BOTTOM_EDGE =6
|
|
947
|
+
DIVISION_MENU_DELETE_ALL =7
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
class PopupDivisionMenu(wx.Menu):
|
|
952
|
+
def __init__(self):
|
|
953
|
+
wx.Menu.__init__(self)
|
|
954
|
+
self.Append(DIVISION_MENU_SPLIT_HORIZONTALLY,"Split horizontally")
|
|
955
|
+
self.Append(DIVISION_MENU_SPLIT_VERTICALLY,"Split vertically")
|
|
956
|
+
self.AppendSeparator()
|
|
957
|
+
self.Append(DIVISION_MENU_EDIT_LEFT_EDGE,"Edit left edge")
|
|
958
|
+
self.Append(DIVISION_MENU_EDIT_TOP_EDGE,"Edit top edge")
|
|
959
|
+
|
|
960
|
+
wx.EVT_MENU_RANGE(self, DIVISION_MENU_SPLIT_HORIZONTALLY, DIVISION_MENU_EDIT_BOTTOM_EDGE, self.OnMenu)
|
|
961
|
+
|
|
962
|
+
def SetClientData(self, data):
|
|
963
|
+
self._clientData = data
|
|
964
|
+
|
|
965
|
+
def GetClientData(self):
|
|
966
|
+
return self._clientData
|
|
967
|
+
|
|
968
|
+
def OnMenu(self, event):
|
|
969
|
+
division = self.GetClientData()
|
|
970
|
+
if event.GetId() == DIVISION_MENU_SPLIT_HORIZONTALLY:
|
|
971
|
+
division.Divide(wx.HORIZONTAL)
|
|
972
|
+
elif event.GetId() == DIVISION_MENU_SPLIT_VERTICALLY:
|
|
973
|
+
division.Divide(wx.VERTICAL)
|
|
974
|
+
elif event.GetId() == DIVISION_MENU_EDIT_LEFT_EDGE:
|
|
975
|
+
division.EditEdge(DIVISION_SIDE_LEFT)
|
|
976
|
+
elif event.GetId() == DIVISION_MENU_EDIT_TOP_EDGE:
|
|
977
|
+
division.EditEdge(DIVISION_SIDE_TOP)
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
class DivisionShape(CompositeShape):
|
|
982
|
+
"""
|
|
983
|
+
A :class:`DivisionShape` class is a composite with special properties,
|
|
984
|
+
to be used for containment. It's a subdivision of a container.
|
|
985
|
+
A containing node image consists of a composite with a main child shape
|
|
986
|
+
such as rounded rectangle, plus a list of division objects.
|
|
987
|
+
It needs to be a composite because a division contains pieces
|
|
988
|
+
of diagram.
|
|
989
|
+
|
|
990
|
+
:note: A container has at least one wxDivisionShape for consistency.
|
|
991
|
+
This can be subdivided, so it turns into two objects, then each of
|
|
992
|
+
these can be subdivided, etc.
|
|
993
|
+
|
|
994
|
+
"""
|
|
995
|
+
def __init__(self):
|
|
996
|
+
"""
|
|
997
|
+
Default class constructor.
|
|
998
|
+
"""
|
|
999
|
+
CompositeShape.__init__(self)
|
|
1000
|
+
self.SetSensitivityFilter(OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_RIGHT)
|
|
1001
|
+
self.SetCentreResize(False)
|
|
1002
|
+
self.SetAttachmentMode(True)
|
|
1003
|
+
self._leftSide = None
|
|
1004
|
+
self._rightSide = None
|
|
1005
|
+
self._topSide = None
|
|
1006
|
+
self._bottomSide = None
|
|
1007
|
+
self._handleSide = DIVISION_SIDE_NONE
|
|
1008
|
+
self._leftSidePen = wx.BLACK_PEN
|
|
1009
|
+
self._topSidePen = wx.BLACK_PEN
|
|
1010
|
+
self._leftSideColour = "BLACK"
|
|
1011
|
+
self._topSideColour = "BLACK"
|
|
1012
|
+
self._leftSideStyle = "Solid"
|
|
1013
|
+
self._topSideStyle = "Solid"
|
|
1014
|
+
self.ClearRegions()
|
|
1015
|
+
|
|
1016
|
+
def SetLeftSide(self, shape):
|
|
1017
|
+
"""Set the the division on the left side of this division."""
|
|
1018
|
+
self._leftSide = shape
|
|
1019
|
+
|
|
1020
|
+
def SetTopSide(self, shape):
|
|
1021
|
+
"""Set the the division on the top side of this division."""
|
|
1022
|
+
self._topSide = shape
|
|
1023
|
+
|
|
1024
|
+
def SetRightSide(self, shape):
|
|
1025
|
+
"""Set the the division on the right side of this division."""
|
|
1026
|
+
self._rightSide = shape
|
|
1027
|
+
|
|
1028
|
+
def SetBottomSide(self, shape):
|
|
1029
|
+
"""Set the the division on the bottom side of this division."""
|
|
1030
|
+
self._bottomSide = shape
|
|
1031
|
+
|
|
1032
|
+
def GetLeftSide(self):
|
|
1033
|
+
"""Return the division on the left side of this division."""
|
|
1034
|
+
return self._leftSide
|
|
1035
|
+
|
|
1036
|
+
def GetTopSide(self):
|
|
1037
|
+
"""Return the division on the top side of this division."""
|
|
1038
|
+
return self._topSide
|
|
1039
|
+
|
|
1040
|
+
def GetRightSide(self):
|
|
1041
|
+
"""Return the division on the right side of this division."""
|
|
1042
|
+
return self._rightSide
|
|
1043
|
+
|
|
1044
|
+
def GetBottomSide(self):
|
|
1045
|
+
"""Return the division on the bottom side of this division."""
|
|
1046
|
+
return self._bottomSide
|
|
1047
|
+
|
|
1048
|
+
def SetHandleSide(self, side):
|
|
1049
|
+
"""
|
|
1050
|
+
Sets the side which the handle appears on.
|
|
1051
|
+
|
|
1052
|
+
:param `side`: Either DIVISION_SIDE_LEFT or DIVISION_SIDE_TOP.
|
|
1053
|
+
|
|
1054
|
+
"""
|
|
1055
|
+
self._handleSide = side
|
|
1056
|
+
|
|
1057
|
+
def GetHandleSide(self):
|
|
1058
|
+
"""Return the side which the handle appears on."""
|
|
1059
|
+
return self._handleSide
|
|
1060
|
+
|
|
1061
|
+
def SetLeftSidePen(self, pen):
|
|
1062
|
+
"""Set the colour for drawing the left side of the division."""
|
|
1063
|
+
self._leftSidePen = pen
|
|
1064
|
+
|
|
1065
|
+
def SetTopSidePen(self, pen):
|
|
1066
|
+
"""Set the colour for drawing the top side of the division."""
|
|
1067
|
+
self._topSidePen = pen
|
|
1068
|
+
|
|
1069
|
+
def GetLeftSidePen(self):
|
|
1070
|
+
"""Return the pen used for drawing the left side of the division."""
|
|
1071
|
+
return self._leftSidePen
|
|
1072
|
+
|
|
1073
|
+
def GetTopSidePen(self):
|
|
1074
|
+
"""Return the pen used for drawing the top side of the division."""
|
|
1075
|
+
return self._topSidePen
|
|
1076
|
+
|
|
1077
|
+
def GetLeftSideColour(self):
|
|
1078
|
+
"""Return the colour used for drawing the left side of the division."""
|
|
1079
|
+
return self._leftSideColour
|
|
1080
|
+
|
|
1081
|
+
def GetTopSideColour(self):
|
|
1082
|
+
"""Return the colour used for drawing the top side of the division."""
|
|
1083
|
+
return self._topSideColour
|
|
1084
|
+
|
|
1085
|
+
def SetLeftSideColour(self, colour):
|
|
1086
|
+
"""Set the colour for drawing the left side of the division."""
|
|
1087
|
+
self._leftSideColour = colour
|
|
1088
|
+
|
|
1089
|
+
def SetTopSideColour(self, colour):
|
|
1090
|
+
"""Set the colour for drawing the top side of the division."""
|
|
1091
|
+
self._topSideColour = colour
|
|
1092
|
+
|
|
1093
|
+
def GetLeftSideStyle(self):
|
|
1094
|
+
"""Return the style used for the left side of the division."""
|
|
1095
|
+
return self._leftSideStyle
|
|
1096
|
+
|
|
1097
|
+
def GetTopSideStyle(self):
|
|
1098
|
+
"""Return the style used for the top side of the division."""
|
|
1099
|
+
return self._topSideStyle
|
|
1100
|
+
|
|
1101
|
+
def SetLeftSideStyle(self, style):
|
|
1102
|
+
"""
|
|
1103
|
+
Set the left side style.
|
|
1104
|
+
|
|
1105
|
+
:param `style`: valid values ???
|
|
1106
|
+
|
|
1107
|
+
"""
|
|
1108
|
+
self._leftSideStyle = style
|
|
1109
|
+
|
|
1110
|
+
def SetTopSideStyle(self, style):
|
|
1111
|
+
"""
|
|
1112
|
+
Set the top side style.
|
|
1113
|
+
|
|
1114
|
+
:param `style`: valid values ???
|
|
1115
|
+
|
|
1116
|
+
"""
|
|
1117
|
+
self._lefttopStyle = style
|
|
1118
|
+
|
|
1119
|
+
def OnDraw(self, dc):
|
|
1120
|
+
"""The draw handler."""
|
|
1121
|
+
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
1122
|
+
dc.SetBackgroundMode(wx.TRANSPARENT)
|
|
1123
|
+
|
|
1124
|
+
x1 = self.GetX() - self.GetWidth() / 2.0
|
|
1125
|
+
y1 = self.GetY() - self.GetHeight() / 2.0
|
|
1126
|
+
x2 = self.GetX() + self.GetWidth() / 2.0
|
|
1127
|
+
y2 = self.GetY() + self.GetHeight() / 2.0
|
|
1128
|
+
|
|
1129
|
+
# Should subtract 1 pixel if drawing under Windows
|
|
1130
|
+
if sys.platform[:3] == "win":
|
|
1131
|
+
y2 -= 1
|
|
1132
|
+
|
|
1133
|
+
if self._leftSide:
|
|
1134
|
+
dc.SetPen(self._leftSidePen)
|
|
1135
|
+
dc.DrawLine(*map(int, (x1, y2, x1, y1)))
|
|
1136
|
+
|
|
1137
|
+
if self._topSide:
|
|
1138
|
+
dc.SetPen(self._topSidePen)
|
|
1139
|
+
dc.DrawLine(*map(int, (x1, y1, x2, y1)))
|
|
1140
|
+
|
|
1141
|
+
# For testing purposes, draw a rectangle so we know
|
|
1142
|
+
# how big the division is.
|
|
1143
|
+
#dc.SetBrush(wx.RED_BRUSH)
|
|
1144
|
+
#dc.DrawRectangle(x1, y1, self.GetWidth(), self.GetHeight())
|
|
1145
|
+
|
|
1146
|
+
def OnDrawContents(self, dc):
|
|
1147
|
+
"""The draw contens handler."""
|
|
1148
|
+
CompositeShape.OnDrawContents(self, dc)
|
|
1149
|
+
|
|
1150
|
+
def OnMovePre(self, dc, x, y, oldx, oldy, display = True):
|
|
1151
|
+
"""The move 'pre' handler."""
|
|
1152
|
+
diffX = x - oldx
|
|
1153
|
+
diffY = y - oldy
|
|
1154
|
+
for object in self._children:
|
|
1155
|
+
object.Erase(dc)
|
|
1156
|
+
object.Move(dc, object.GetX() + diffX, object.GetY() + diffY, display)
|
|
1157
|
+
return True
|
|
1158
|
+
|
|
1159
|
+
def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
|
|
1160
|
+
"""The drag left handler."""
|
|
1161
|
+
if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
|
|
1162
|
+
if self._parent:
|
|
1163
|
+
hit = self._parent.HitTest(x, y)
|
|
1164
|
+
if hit:
|
|
1165
|
+
attachment, dist = hit
|
|
1166
|
+
self._parent.GetEventHandler().OnDragLeft(draw, x, y, keys, attachment)
|
|
1167
|
+
return
|
|
1168
|
+
Shape.OnDragLeft(self, draw, x, y, keys, attachment)
|
|
1169
|
+
|
|
1170
|
+
def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
1171
|
+
"""The begin drag left handler."""
|
|
1172
|
+
if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
|
|
1173
|
+
if self._parent:
|
|
1174
|
+
hit = self._parent.HitTest(x, y)
|
|
1175
|
+
if hit:
|
|
1176
|
+
attachment, dist = hit
|
|
1177
|
+
self._parent.GetEventHandler().OnBeginDragLeft(x, y, keys, attachment)
|
|
1178
|
+
return
|
|
1179
|
+
Shape.OnBeginDragLeft(x, y, keys, attachment)
|
|
1180
|
+
|
|
1181
|
+
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
1182
|
+
"""The end drag left handler."""
|
|
1183
|
+
if self._canvas.HasCapture():
|
|
1184
|
+
self._canvas.ReleaseMouse()
|
|
1185
|
+
if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
|
|
1186
|
+
if self._parent:
|
|
1187
|
+
hit = self._parent.HitTest(x, y)
|
|
1188
|
+
if hit:
|
|
1189
|
+
attachment, dist = hit
|
|
1190
|
+
self._parent.GetEventHandler().OnEndDragLeft(x, y, keys, attachment)
|
|
1191
|
+
return
|
|
1192
|
+
|
|
1193
|
+
dc = wx.MemoryDC()
|
|
1194
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1195
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1196
|
+
dc.SetLogicalFunction(wx.COPY)
|
|
1197
|
+
|
|
1198
|
+
self._xpos, self._ypos = self._canvas.Snap(self._xpos, self._ypos)
|
|
1199
|
+
self.GetEventHandler().OnMovePre(dc, x, y, self._oldX, self._oldY)
|
|
1200
|
+
|
|
1201
|
+
self.ResetControlPoints()
|
|
1202
|
+
self.Draw(dc)
|
|
1203
|
+
self.MoveLinks(dc)
|
|
1204
|
+
self.GetEventHandler().OnDrawControlPoints(dc)
|
|
1205
|
+
|
|
1206
|
+
if self._canvas and not self._canvas.GetQuickEditMode():
|
|
1207
|
+
self._canvas.Redraw(dc)
|
|
1208
|
+
|
|
1209
|
+
def SetSize(self, w, h, recursive = True):
|
|
1210
|
+
"""
|
|
1211
|
+
Set the size.
|
|
1212
|
+
|
|
1213
|
+
:param `w`: the width
|
|
1214
|
+
:param `h`: the heigth
|
|
1215
|
+
:param `recursive`: `True` recurse all children
|
|
1216
|
+
|
|
1217
|
+
"""
|
|
1218
|
+
self._width = w
|
|
1219
|
+
self._height = h
|
|
1220
|
+
RectangleShape.SetSize(self, w, h, recursive)
|
|
1221
|
+
|
|
1222
|
+
def CalculateSize(self):
|
|
1223
|
+
"""not implemented???"""
|
|
1224
|
+
pass
|
|
1225
|
+
|
|
1226
|
+
# Experimental
|
|
1227
|
+
def OnRightClick(self, x, y, keys = 0, attachment = 0):
|
|
1228
|
+
"""The right click handler."""
|
|
1229
|
+
if keys & KEY_CTRL:
|
|
1230
|
+
self.PopupMenu(x, y)
|
|
1231
|
+
else:
|
|
1232
|
+
if self._parent:
|
|
1233
|
+
hit = self._parent.HitTest(x, y)
|
|
1234
|
+
if hit:
|
|
1235
|
+
attachment, dist = hit
|
|
1236
|
+
self._parent.GetEventHandler().OnRightClick(x, y, keys, attachment)
|
|
1237
|
+
|
|
1238
|
+
def Divide(self, direction):
|
|
1239
|
+
"""Divide this division into two further divisions.
|
|
1240
|
+
|
|
1241
|
+
:param `direction`: `wx.HORIZONTAL` for horizontal or `wx.VERTICAL` for
|
|
1242
|
+
vertical division.
|
|
1243
|
+
|
|
1244
|
+
"""
|
|
1245
|
+
# Calculate existing top-left, bottom-right
|
|
1246
|
+
x1 = self.GetX() - self.GetWidth() / 2.0
|
|
1247
|
+
y1 = self.GetY() - self.GetHeight() / 2.0
|
|
1248
|
+
|
|
1249
|
+
compositeParent = self.GetParent()
|
|
1250
|
+
oldWidth = self.GetWidth()
|
|
1251
|
+
oldHeight = self.GetHeight()
|
|
1252
|
+
if self.Selected():
|
|
1253
|
+
self.Select(False)
|
|
1254
|
+
|
|
1255
|
+
dc = wx.MemoryDC()
|
|
1256
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1257
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1258
|
+
|
|
1259
|
+
if direction == wx.VERTICAL:
|
|
1260
|
+
# Dividing vertically means notionally putting a horizontal
|
|
1261
|
+
# line through it.
|
|
1262
|
+
# Break existing piece into two.
|
|
1263
|
+
newXPos1 = self.GetX()
|
|
1264
|
+
newYPos1 = y1 + self.GetHeight() / 4.0
|
|
1265
|
+
newXPos2 = self.GetX()
|
|
1266
|
+
newYPos2 = y1 + 3 * self.GetHeight() / 4.0
|
|
1267
|
+
newDivision = compositeParent.OnCreateDivision()
|
|
1268
|
+
newDivision.Show(True)
|
|
1269
|
+
|
|
1270
|
+
self.Erase(dc)
|
|
1271
|
+
|
|
1272
|
+
# Anything adjoining the bottom of this division now adjoins the
|
|
1273
|
+
# bottom of the new division.
|
|
1274
|
+
for obj in compositeParent.GetDivisions():
|
|
1275
|
+
if obj.GetTopSide() == self:
|
|
1276
|
+
obj.SetTopSide(newDivision)
|
|
1277
|
+
|
|
1278
|
+
newDivision.SetTopSide(self)
|
|
1279
|
+
newDivision.SetBottomSide(self._bottomSide)
|
|
1280
|
+
newDivision.SetLeftSide(self._leftSide)
|
|
1281
|
+
newDivision.SetRightSide(self._rightSide)
|
|
1282
|
+
self._bottomSide = newDivision
|
|
1283
|
+
|
|
1284
|
+
compositeParent.GetDivisions().append(newDivision)
|
|
1285
|
+
|
|
1286
|
+
# CHANGE: Need to insert this division at start of divisions in the
|
|
1287
|
+
# object list, because e.g.:
|
|
1288
|
+
# 1) Add division
|
|
1289
|
+
# 2) Add contained object
|
|
1290
|
+
# 3) Add division
|
|
1291
|
+
# Division is now receiving mouse events _before_ the contained
|
|
1292
|
+
# object, because it was added last (on top of all others)
|
|
1293
|
+
|
|
1294
|
+
# Add after the image that visualizes the container
|
|
1295
|
+
compositeParent.AddChild(newDivision, compositeParent.FindContainerImage())
|
|
1296
|
+
|
|
1297
|
+
self._handleSide = DIVISION_SIDE_BOTTOM
|
|
1298
|
+
newDivision.SetHandleSide(DIVISION_SIDE_TOP)
|
|
1299
|
+
|
|
1300
|
+
self.SetSize(oldWidth, oldHeight / 2.0)
|
|
1301
|
+
self.Move(dc, newXPos1, newYPos1)
|
|
1302
|
+
|
|
1303
|
+
newDivision.SetSize(oldWidth, oldHeight / 2.0)
|
|
1304
|
+
newDivision.Move(dc, newXPos2, newYPos2)
|
|
1305
|
+
else:
|
|
1306
|
+
# Dividing horizontally means notionally putting a vertical line
|
|
1307
|
+
# through it.
|
|
1308
|
+
# Break existing piece into two.
|
|
1309
|
+
newXPos1 = x1 + self.GetWidth() / 4.0
|
|
1310
|
+
newYPos1 = self.GetY()
|
|
1311
|
+
newXPos2 = x1 + 3 * self.GetWidth() / 4.0
|
|
1312
|
+
newYPos2 = self.GetY()
|
|
1313
|
+
newDivision = compositeParent.OnCreateDivision()
|
|
1314
|
+
newDivision.Show(True)
|
|
1315
|
+
|
|
1316
|
+
self.Erase(dc)
|
|
1317
|
+
|
|
1318
|
+
# Anything adjoining the left of this division now adjoins the
|
|
1319
|
+
# left of the new division.
|
|
1320
|
+
for obj in compositeParent.GetDivisions():
|
|
1321
|
+
if obj.GetLeftSide() == self:
|
|
1322
|
+
obj.SetLeftSide(newDivision)
|
|
1323
|
+
|
|
1324
|
+
newDivision.SetTopSide(self._topSide)
|
|
1325
|
+
newDivision.SetBottomSide(self._bottomSide)
|
|
1326
|
+
newDivision.SetLeftSide(self)
|
|
1327
|
+
newDivision.SetRightSide(self._rightSide)
|
|
1328
|
+
self._rightSide = newDivision
|
|
1329
|
+
|
|
1330
|
+
compositeParent.GetDivisions().append(newDivision)
|
|
1331
|
+
compositeParent.AddChild(newDivision, compositeParent.FindContainerImage())
|
|
1332
|
+
|
|
1333
|
+
self._handleSide = DIVISION_SIDE_RIGHT
|
|
1334
|
+
newDivision.SetHandleSide(DIVISION_SIDE_LEFT)
|
|
1335
|
+
|
|
1336
|
+
self.SetSize(oldWidth / 2.0, oldHeight)
|
|
1337
|
+
self.Move(dc, newXPos1, newYPos1)
|
|
1338
|
+
|
|
1339
|
+
newDivision.SetSize(oldWidth / 2.0, oldHeight)
|
|
1340
|
+
newDivision.Move(dc, newXPos2, newYPos2)
|
|
1341
|
+
|
|
1342
|
+
if compositeParent.Selected():
|
|
1343
|
+
compositeParent.DeleteControlPoints(dc)
|
|
1344
|
+
compositeParent.MakeControlPoints()
|
|
1345
|
+
compositeParent.MakeMandatoryControlPoints()
|
|
1346
|
+
|
|
1347
|
+
compositeParent.Draw(dc)
|
|
1348
|
+
return True
|
|
1349
|
+
|
|
1350
|
+
def MakeControlPoints(self):
|
|
1351
|
+
"""Make control points."""
|
|
1352
|
+
self.MakeMandatoryControlPoints()
|
|
1353
|
+
|
|
1354
|
+
def MakeMandatoryControlPoints(self):
|
|
1355
|
+
"""Make mandatory control points."""
|
|
1356
|
+
maxX, maxY = self.GetBoundingBoxMax()
|
|
1357
|
+
x = y = 0.0
|
|
1358
|
+
direction = 0
|
|
1359
|
+
|
|
1360
|
+
if self._handleSide == DIVISION_SIDE_LEFT:
|
|
1361
|
+
x = -maxX / 2.0
|
|
1362
|
+
direction = CONTROL_POINT_HORIZONTAL
|
|
1363
|
+
elif self._handleSide == DIVISION_SIDE_TOP:
|
|
1364
|
+
y = -maxY / 2.0
|
|
1365
|
+
direction = CONTROL_POINT_VERTICAL
|
|
1366
|
+
elif self._handleSide == DIVISION_SIDE_RIGHT:
|
|
1367
|
+
x = maxX / 2.0
|
|
1368
|
+
direction = CONTROL_POINT_HORIZONTAL
|
|
1369
|
+
elif self._handleSide == DIVISION_SIDE_BOTTOM:
|
|
1370
|
+
y = maxY / 2.0
|
|
1371
|
+
direction = CONTROL_POINT_VERTICAL
|
|
1372
|
+
|
|
1373
|
+
if self._handleSide != DIVISION_SIDE_NONE:
|
|
1374
|
+
control = DivisionControlPoint(self._canvas, self, CONTROL_POINT_SIZE, x, y, direction)
|
|
1375
|
+
self._canvas.AddShape(control)
|
|
1376
|
+
self._controlPoints.append(control)
|
|
1377
|
+
|
|
1378
|
+
def ResetControlPoints(self):
|
|
1379
|
+
"""Reset control points."""
|
|
1380
|
+
self.ResetMandatoryControlPoints()
|
|
1381
|
+
|
|
1382
|
+
def ResetMandatoryControlPoints(self):
|
|
1383
|
+
"""Reset mandatory control points."""
|
|
1384
|
+
if not self._controlPoints:
|
|
1385
|
+
return
|
|
1386
|
+
|
|
1387
|
+
maxX, maxY = self.GetBoundingBoxMax()
|
|
1388
|
+
|
|
1389
|
+
node = self._controlPoints[0]
|
|
1390
|
+
|
|
1391
|
+
if self._handleSide == DIVISION_SIDE_LEFT and node:
|
|
1392
|
+
node._xoffset = -maxX / 2.0
|
|
1393
|
+
node._yoffset = 0.0
|
|
1394
|
+
|
|
1395
|
+
if self._handleSide == DIVISION_SIDE_TOP and node:
|
|
1396
|
+
node._xoffset = 0.0
|
|
1397
|
+
node._yoffset = -maxY / 2.0
|
|
1398
|
+
|
|
1399
|
+
if self._handleSide == DIVISION_SIDE_RIGHT and node:
|
|
1400
|
+
node._xoffset = maxX / 2.0
|
|
1401
|
+
node._yoffset = 0.0
|
|
1402
|
+
|
|
1403
|
+
if self._handleSide == DIVISION_SIDE_BOTTOM and node:
|
|
1404
|
+
node._xoffset = 0.0
|
|
1405
|
+
node._yoffset = maxY / 2.0
|
|
1406
|
+
|
|
1407
|
+
def AdjustLeft(self, left, test):
|
|
1408
|
+
"""
|
|
1409
|
+
Adjust a side.
|
|
1410
|
+
|
|
1411
|
+
:param `left`: desired left position ???
|
|
1412
|
+
:param `test`: if `True` just a test
|
|
1413
|
+
:returns: `False` if it's not physically possible to adjust it to
|
|
1414
|
+
this point.
|
|
1415
|
+
"""
|
|
1416
|
+
x2 = self.GetX() + self.GetWidth() / 2.0
|
|
1417
|
+
|
|
1418
|
+
if left >= x2:
|
|
1419
|
+
return False
|
|
1420
|
+
|
|
1421
|
+
if test:
|
|
1422
|
+
return True
|
|
1423
|
+
|
|
1424
|
+
newW = x2 - left
|
|
1425
|
+
newX = left + newW / 2.0
|
|
1426
|
+
self.SetSize(newW, self.GetHeight())
|
|
1427
|
+
|
|
1428
|
+
dc = wx.MemoryDC()
|
|
1429
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1430
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1431
|
+
|
|
1432
|
+
self.Move(dc, newX, self.GetY())
|
|
1433
|
+
return True
|
|
1434
|
+
|
|
1435
|
+
def AdjustRight(self, right, test):
|
|
1436
|
+
"""
|
|
1437
|
+
Adjust a side.
|
|
1438
|
+
|
|
1439
|
+
:param `right`: desired right position ???
|
|
1440
|
+
:param `test`: if `True` just a test
|
|
1441
|
+
:returns: `False` if it's not physically possible to adjust it to
|
|
1442
|
+
this point.
|
|
1443
|
+
|
|
1444
|
+
"""
|
|
1445
|
+
x1 = self.GetX() - self.GetWidth() / 2.0
|
|
1446
|
+
|
|
1447
|
+
if right <= x1:
|
|
1448
|
+
return False
|
|
1449
|
+
|
|
1450
|
+
if test:
|
|
1451
|
+
return True
|
|
1452
|
+
|
|
1453
|
+
newW = right - x1
|
|
1454
|
+
newX = x1 + newW / 2.0
|
|
1455
|
+
self.SetSize(newW, self.GetHeight())
|
|
1456
|
+
|
|
1457
|
+
dc = wx.MemoryDC()
|
|
1458
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1459
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1460
|
+
|
|
1461
|
+
self.Move(dc, newX, self.GetY())
|
|
1462
|
+
return True
|
|
1463
|
+
|
|
1464
|
+
def AdjustTop(self, top, test):
|
|
1465
|
+
"""
|
|
1466
|
+
Adjust a side.
|
|
1467
|
+
|
|
1468
|
+
:param `top`: desired top position ???
|
|
1469
|
+
:param `test`: if `True` just a test
|
|
1470
|
+
:returns: `False` if it's not physically possible to adjust it to
|
|
1471
|
+
this point.
|
|
1472
|
+
|
|
1473
|
+
"""
|
|
1474
|
+
y1 = self.GetY() - self.GetHeight() / 2.0
|
|
1475
|
+
|
|
1476
|
+
if top <= y1:
|
|
1477
|
+
return False
|
|
1478
|
+
|
|
1479
|
+
if test:
|
|
1480
|
+
return True
|
|
1481
|
+
|
|
1482
|
+
newH = top - y1
|
|
1483
|
+
newY = y1 + newH / 2.0
|
|
1484
|
+
self.SetSize(self.GetWidth(), newH)
|
|
1485
|
+
|
|
1486
|
+
dc = wx.MemoryDC()
|
|
1487
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1488
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1489
|
+
|
|
1490
|
+
self.Move(dc, self.GetX(), newY)
|
|
1491
|
+
return True
|
|
1492
|
+
|
|
1493
|
+
# Resize adjoining divisions.
|
|
1494
|
+
|
|
1495
|
+
# Behaviour should be as follows:
|
|
1496
|
+
# If right edge moves, find all objects whose left edge
|
|
1497
|
+
# adjoins this object, and move left edge accordingly.
|
|
1498
|
+
# If left..., move ... right.
|
|
1499
|
+
# If top..., move ... bottom.
|
|
1500
|
+
# If bottom..., move top.
|
|
1501
|
+
# If size goes to zero or end position is other side of start position,
|
|
1502
|
+
# resize to original size and return.
|
|
1503
|
+
#
|
|
1504
|
+
def ResizeAdjoining(self, side, newPos, test):
|
|
1505
|
+
"""
|
|
1506
|
+
Resize adjoining divisions at the given side.
|
|
1507
|
+
|
|
1508
|
+
:param `side`: can be one of
|
|
1509
|
+
|
|
1510
|
+
======================= =======================
|
|
1511
|
+
Side option Description
|
|
1512
|
+
======================= =======================
|
|
1513
|
+
`DIVISION_SIDE_NONE` no side
|
|
1514
|
+
`DIVISION_SIDE_LEFT` Left side
|
|
1515
|
+
`DIVISION_SIDE_TOP` Top side
|
|
1516
|
+
`DIVISION_SIDE_RIGHT` Right side
|
|
1517
|
+
`DIVISION_SIDE_BOTTOM` Bottom side
|
|
1518
|
+
======================= =======================
|
|
1519
|
+
|
|
1520
|
+
:param `newPos`: new position
|
|
1521
|
+
:param `test`: if `True`, just see whether it's possible for each
|
|
1522
|
+
adjoining region, returning `False` if it's not.
|
|
1523
|
+
|
|
1524
|
+
"""
|
|
1525
|
+
divisionParent = self.GetParent()
|
|
1526
|
+
for division in divisionParent.GetDivisions():
|
|
1527
|
+
if side == DIVISION_SIDE_LEFT:
|
|
1528
|
+
if division._rightSide == self:
|
|
1529
|
+
success = division.AdjustRight(newPos, test)
|
|
1530
|
+
if not success and test:
|
|
1531
|
+
return False
|
|
1532
|
+
elif side == DIVISION_SIDE_TOP:
|
|
1533
|
+
if division._bottomSide == self:
|
|
1534
|
+
success = division.AdjustBottom(newPos, test)
|
|
1535
|
+
if not success and test:
|
|
1536
|
+
return False
|
|
1537
|
+
elif side == DIVISION_SIDE_RIGHT:
|
|
1538
|
+
if division._leftSide == self:
|
|
1539
|
+
success = division.AdjustLeft(newPos, test)
|
|
1540
|
+
if not success and test:
|
|
1541
|
+
return False
|
|
1542
|
+
elif side == DIVISION_SIDE_BOTTOM:
|
|
1543
|
+
if division._topSide == self:
|
|
1544
|
+
success = division.AdjustTop(newPos, test)
|
|
1545
|
+
if not success and test:
|
|
1546
|
+
return False
|
|
1547
|
+
return True
|
|
1548
|
+
|
|
1549
|
+
def EditEdge(self, side):
|
|
1550
|
+
print("EditEdge() not implemented.")
|
|
1551
|
+
|
|
1552
|
+
def PopupMenu(self, x, y):
|
|
1553
|
+
"""Popup menu handler."""
|
|
1554
|
+
menu = PopupDivisionMenu()
|
|
1555
|
+
menu.SetClientData(self)
|
|
1556
|
+
if self._leftSide:
|
|
1557
|
+
menu.Enable(DIVISION_MENU_EDIT_LEFT_EDGE, True)
|
|
1558
|
+
else:
|
|
1559
|
+
menu.Enable(DIVISION_MENU_EDIT_LEFT_EDGE, False)
|
|
1560
|
+
if self._topSide:
|
|
1561
|
+
menu.Enable(DIVISION_MENU_EDIT_TOP_EDGE, True)
|
|
1562
|
+
else:
|
|
1563
|
+
menu.Enable(DIVISION_MENU_EDIT_TOP_EDGE, False)
|
|
1564
|
+
|
|
1565
|
+
x1, y1 = self._canvas.GetViewStart()
|
|
1566
|
+
unit_x, unit_y = self._canvas.GetScrollPixelsPerUnit()
|
|
1567
|
+
|
|
1568
|
+
dc = wx.MemoryDC()
|
|
1569
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1570
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1571
|
+
|
|
1572
|
+
mouse_x = dc.LogicalToDeviceX(x - x1 * unit_x)
|
|
1573
|
+
mouse_y = dc.LogicalToDeviceY(y - y1 * unit_y)
|
|
1574
|
+
|
|
1575
|
+
self._canvas.PopupMenu(menu, (mouse_x, mouse_y))
|
|
1576
|
+
|
|
1577
|
+
|