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/lines.py
ADDED
|
@@ -0,0 +1,1811 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#----------------------------------------------------------------------------
|
|
3
|
+
# Name: lines.py
|
|
4
|
+
# Purpose: LineShape 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.lines.LineShape` class may have arrowheads at the
|
|
16
|
+
beginning and end.
|
|
17
|
+
"""
|
|
18
|
+
import sys
|
|
19
|
+
import math
|
|
20
|
+
|
|
21
|
+
from .basic import Shape, ShapeRegion, ShapeTextLine, ControlPoint, RectangleShape
|
|
22
|
+
from .oglmisc import *
|
|
23
|
+
|
|
24
|
+
# Line alignment flags
|
|
25
|
+
# Vertical by default
|
|
26
|
+
LINE_ALIGNMENT_HORIZ = 1
|
|
27
|
+
LINE_ALIGNMENT_VERT = 0
|
|
28
|
+
LINE_ALIGNMENT_TO_NEXT_HANDLE = 2
|
|
29
|
+
LINE_ALIGNMENT_NONE = 0
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class LineControlPoint(ControlPoint):
|
|
34
|
+
"""
|
|
35
|
+
The :class:`LineControlPoint` class.
|
|
36
|
+
"""
|
|
37
|
+
def __init__(self, theCanvas = None, object = None, size = 0.0, x = 0.0, y = 0.0, the_type = 0):
|
|
38
|
+
"""
|
|
39
|
+
Default class constructor.
|
|
40
|
+
|
|
41
|
+
:param `theCanvas`: a :class:`~lib.ogl.Canvas`
|
|
42
|
+
:param `object`: not used ???
|
|
43
|
+
:param float `size`: the size
|
|
44
|
+
:param float `x`: the x position
|
|
45
|
+
:param float `y`: the y position
|
|
46
|
+
:param int `the_type`: one of the following types
|
|
47
|
+
|
|
48
|
+
======================================== ==================================
|
|
49
|
+
Control point type Description
|
|
50
|
+
======================================== ==================================
|
|
51
|
+
`CONTROL_POINT_VERTICAL` Vertical
|
|
52
|
+
`CONTROL_POINT_HORIZONTAL` Horizontal
|
|
53
|
+
`CONTROL_POINT_DIAGONAL` Diagonal
|
|
54
|
+
======================================== ==================================
|
|
55
|
+
|
|
56
|
+
"""
|
|
57
|
+
ControlPoint.__init__(self, theCanvas, object, size, x, y, the_type)
|
|
58
|
+
self._xpos = x
|
|
59
|
+
self._ypos = y
|
|
60
|
+
self._type = the_type
|
|
61
|
+
self._point = None
|
|
62
|
+
self._originalPos = None
|
|
63
|
+
|
|
64
|
+
def OnDraw(self, dc):
|
|
65
|
+
"""The draw handler."""
|
|
66
|
+
RectangleShape.OnDraw(self, dc)
|
|
67
|
+
|
|
68
|
+
# Implement movement of Line point
|
|
69
|
+
def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
|
|
70
|
+
"""The drag left handler."""
|
|
71
|
+
self._shape.GetEventHandler().OnSizingDragLeft(self, draw, x, y, keys, attachment)
|
|
72
|
+
|
|
73
|
+
def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
74
|
+
"""The begin drag left handler."""
|
|
75
|
+
self._shape.GetEventHandler().OnSizingBeginDragLeft(self, x, y, keys, attachment)
|
|
76
|
+
|
|
77
|
+
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
78
|
+
"""The end drag left handler."""
|
|
79
|
+
self._shape.GetEventHandler().OnSizingEndDragLeft(self, x, y, keys, attachment)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class ArrowHead(object):
|
|
84
|
+
"""
|
|
85
|
+
The arrow head class.
|
|
86
|
+
"""
|
|
87
|
+
def __init__(self, type = 0, end = 0, size = 0.0, dist = 0.0, name = "", mf = None, arrowId = -1):
|
|
88
|
+
"""
|
|
89
|
+
Default class constructor.
|
|
90
|
+
|
|
91
|
+
:param int `type`: the type
|
|
92
|
+
|
|
93
|
+
======================================== ==================================
|
|
94
|
+
Arrow head type Description
|
|
95
|
+
======================================== ==================================
|
|
96
|
+
`ARROW_HOLLOW_CIRCLE` a hollow circle
|
|
97
|
+
`ARROW_FILLED_CIRCLE` a filled circle
|
|
98
|
+
`ARROW_ARROW` an arrow
|
|
99
|
+
`ARROW_SINGLE_OBLIQUE` a single oblique
|
|
100
|
+
`ARROW_DOUBLE_OBLIQUE` a double oblique
|
|
101
|
+
`ARROW_METAFILE` custom, define in metafile
|
|
102
|
+
======================================== ==================================
|
|
103
|
+
|
|
104
|
+
:param int `end`: end of arrow head ???
|
|
105
|
+
:param float `size`: size of arrow head
|
|
106
|
+
:param float `dist`: dist ???
|
|
107
|
+
:param string `name`: name of arrow head
|
|
108
|
+
:param `mf`: mf ???
|
|
109
|
+
:param `arrowId`: id of arrow head
|
|
110
|
+
|
|
111
|
+
"""
|
|
112
|
+
if isinstance(type, ArrowHead):
|
|
113
|
+
pass
|
|
114
|
+
else:
|
|
115
|
+
self._arrowType = type
|
|
116
|
+
self._arrowEnd = end
|
|
117
|
+
self._arrowSize = size
|
|
118
|
+
self._xOffset = dist
|
|
119
|
+
self._yOffset = 0.0
|
|
120
|
+
self._spacing = 5.0
|
|
121
|
+
|
|
122
|
+
self._arrowName = name
|
|
123
|
+
self._metaFile = mf
|
|
124
|
+
self._id = arrowId
|
|
125
|
+
if self._id == -1:
|
|
126
|
+
self._id = wx.NewIdRef()
|
|
127
|
+
|
|
128
|
+
def _GetType(self):
|
|
129
|
+
return self._arrowType
|
|
130
|
+
|
|
131
|
+
def GetPosition(self):
|
|
132
|
+
"""Get end position."""
|
|
133
|
+
return self._arrowEnd
|
|
134
|
+
|
|
135
|
+
def SetPosition(self, pos):
|
|
136
|
+
"""Set end position.
|
|
137
|
+
|
|
138
|
+
:param `pos`: position to set it to
|
|
139
|
+
"""
|
|
140
|
+
self._arrowEnd = pos
|
|
141
|
+
|
|
142
|
+
def GetXOffset(self):
|
|
143
|
+
"""Get the X offset."""
|
|
144
|
+
return self._xOffset
|
|
145
|
+
|
|
146
|
+
def GetYOffset(self):
|
|
147
|
+
"""Get the Y offset."""
|
|
148
|
+
return self._yOffset
|
|
149
|
+
|
|
150
|
+
def GetSpacing(self):
|
|
151
|
+
"""Get the spacing."""
|
|
152
|
+
return self._spacing
|
|
153
|
+
|
|
154
|
+
def GetSize(self):
|
|
155
|
+
"""Get the arrow size."""
|
|
156
|
+
return self._arrowSize
|
|
157
|
+
|
|
158
|
+
def SetSize(self, size):
|
|
159
|
+
"""Set the arrow size.
|
|
160
|
+
|
|
161
|
+
:param `size`: size in points???
|
|
162
|
+
|
|
163
|
+
:note: if a custom arrow is used size is used to scale the arrow???
|
|
164
|
+
"""
|
|
165
|
+
self._arrowSize = size
|
|
166
|
+
if self._arrowType == ARROW_METAFILE and self._metaFile:
|
|
167
|
+
oldWidth = self._metaFile._width
|
|
168
|
+
if oldWidth == 0:
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
scale = float(size) / oldWidth
|
|
172
|
+
if scale != 1:
|
|
173
|
+
self._metaFile.Scale(scale, scale)
|
|
174
|
+
|
|
175
|
+
def GetName(self):
|
|
176
|
+
"""Get the arrow name."""
|
|
177
|
+
return self._arrowName
|
|
178
|
+
|
|
179
|
+
def SetXOffset(self, x):
|
|
180
|
+
"""Set the X offset.
|
|
181
|
+
|
|
182
|
+
:param `x`: value to set the offset to???
|
|
183
|
+
"""
|
|
184
|
+
self._xOffset = x
|
|
185
|
+
|
|
186
|
+
def SetYOffset(self, y):
|
|
187
|
+
"""Set the Y offset.
|
|
188
|
+
|
|
189
|
+
:param `y`: value to set the offset to???
|
|
190
|
+
"""
|
|
191
|
+
self._yOffset = y
|
|
192
|
+
|
|
193
|
+
def GetMetaFile(self):
|
|
194
|
+
"""Get the metafile."""
|
|
195
|
+
return self._metaFile
|
|
196
|
+
|
|
197
|
+
def GetId(self):
|
|
198
|
+
"""Get the id."""
|
|
199
|
+
return self._id
|
|
200
|
+
|
|
201
|
+
def GetArrowEnd(self):
|
|
202
|
+
"""Get the arrow end position."""
|
|
203
|
+
return self._arrowEnd
|
|
204
|
+
|
|
205
|
+
def GetArrowSize(self):
|
|
206
|
+
"""Get the arrow size."""
|
|
207
|
+
return self._arrowSize
|
|
208
|
+
|
|
209
|
+
def SetSpacing(self, sp):
|
|
210
|
+
"""Set the spacing.
|
|
211
|
+
|
|
212
|
+
:param `sp`: the new spacing value
|
|
213
|
+
"""
|
|
214
|
+
self._spacing = sp
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class LabelShape(RectangleShape):
|
|
219
|
+
"""
|
|
220
|
+
The label shape class.
|
|
221
|
+
"""
|
|
222
|
+
def __init__(self, parent, region, w, h):
|
|
223
|
+
"""
|
|
224
|
+
Default class constructor.
|
|
225
|
+
|
|
226
|
+
:param `parent`: the parent an instance of :class:`Line`
|
|
227
|
+
:param `region`: the shape region an instance of :class:`~lib.ogl.ShapeRegion`
|
|
228
|
+
:param `w`: width in points
|
|
229
|
+
:param `h`: heigth in points
|
|
230
|
+
|
|
231
|
+
"""
|
|
232
|
+
RectangleShape.__init__(self, w, h)
|
|
233
|
+
self._lineShape = parent
|
|
234
|
+
self._shapeRegion = region
|
|
235
|
+
self.SetPen(wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT))
|
|
236
|
+
|
|
237
|
+
def OnDraw(self, dc):
|
|
238
|
+
"""The draw handler."""
|
|
239
|
+
if self._lineShape and not self._lineShape.GetDrawHandles():
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
x1 = self._xpos - self._width / 2.0
|
|
243
|
+
y1 = self._ypos - self._height / 2.0
|
|
244
|
+
|
|
245
|
+
if self._pen:
|
|
246
|
+
if self._pen.GetWidth() == 0:
|
|
247
|
+
dc.SetPen(wx.Pen(wx.WHITE, 1, wx.TRANSPARENT))
|
|
248
|
+
else:
|
|
249
|
+
dc.SetPen(self._pen)
|
|
250
|
+
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
251
|
+
|
|
252
|
+
if self._cornerRadius > 0:
|
|
253
|
+
dc.DrawRoundedRectangle(x1, y1, self._width, self._height, self._cornerRadius)
|
|
254
|
+
else:
|
|
255
|
+
dc.DrawRectangle(x1, y1, self._width, self._height)
|
|
256
|
+
|
|
257
|
+
def OnDrawContents(self, dc):
|
|
258
|
+
"""not implemented???"""
|
|
259
|
+
pass
|
|
260
|
+
|
|
261
|
+
def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
|
|
262
|
+
"""The drag left handler."""
|
|
263
|
+
RectangleShape.OnDragLeft(self, draw, x, y, keys, attachment)
|
|
264
|
+
|
|
265
|
+
def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
266
|
+
"""The begin drag left handler."""
|
|
267
|
+
RectangleShape.OnBeginDragLeft(self, x, y, keys, attachment)
|
|
268
|
+
|
|
269
|
+
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
270
|
+
"""The end drag left handler."""
|
|
271
|
+
RectangleShape.OnEndDragLeft(self, x, y, keys, attachment)
|
|
272
|
+
|
|
273
|
+
def OnMovePre(self, dc, x, y, old_x, old_y, display):
|
|
274
|
+
"""The move 'pre' handler.???"""
|
|
275
|
+
return self._lineShape.OnLabelMovePre(dc, self, x, y, old_x, old_y, display)
|
|
276
|
+
|
|
277
|
+
# Divert left and right clicks to line object
|
|
278
|
+
def OnLeftClick(self, x, y, keys = 0, attachment = 0):
|
|
279
|
+
"""The left click handler."""
|
|
280
|
+
self._lineShape.GetEventHandler().OnLeftClick(x, y, keys, attachment)
|
|
281
|
+
|
|
282
|
+
def OnRightClick(self, x, y, keys = 0, attachment = 0):
|
|
283
|
+
"""The right click handler."""
|
|
284
|
+
self._lineShape.GetEventHandler().OnRightClick(x, y, keys, attachment)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class LineShape(Shape):
|
|
289
|
+
"""
|
|
290
|
+
The LineShape class may be attached to two nodes, it may be segmented,
|
|
291
|
+
in which case a control point is drawn for each joint.
|
|
292
|
+
|
|
293
|
+
A :class:`LineShape` may have arrows at the beginning, end and centre.
|
|
294
|
+
"""
|
|
295
|
+
def __init__(self):
|
|
296
|
+
"""
|
|
297
|
+
Default class constructor.
|
|
298
|
+
|
|
299
|
+
"""
|
|
300
|
+
Shape.__init__(self)
|
|
301
|
+
|
|
302
|
+
self._sensitivity = OP_CLICK_LEFT | OP_CLICK_RIGHT
|
|
303
|
+
self._draggable = False
|
|
304
|
+
self._attachmentTo = 0
|
|
305
|
+
self._attachmentFrom = 0
|
|
306
|
+
self._from = None
|
|
307
|
+
self._to = None
|
|
308
|
+
self._erasing = False
|
|
309
|
+
self._arrowSpacing = 5.0
|
|
310
|
+
self._ignoreArrowOffsets = False
|
|
311
|
+
self._isSpline = False
|
|
312
|
+
self._maintainStraightLines = False
|
|
313
|
+
self._alignmentStart = 0
|
|
314
|
+
self._alignmentEnd = 0
|
|
315
|
+
|
|
316
|
+
self._lineControlPoints = None
|
|
317
|
+
|
|
318
|
+
# Clear any existing regions (created in an earlier constructor)
|
|
319
|
+
# and make the three line regions.
|
|
320
|
+
self.ClearRegions()
|
|
321
|
+
for name in ["Middle","Start","End"]:
|
|
322
|
+
newRegion = ShapeRegion()
|
|
323
|
+
newRegion.SetName(name)
|
|
324
|
+
newRegion.SetSize(150, 50)
|
|
325
|
+
self._regions.append(newRegion)
|
|
326
|
+
|
|
327
|
+
self._labelObjects = [None, None, None]
|
|
328
|
+
self._lineOrientations = []
|
|
329
|
+
self._lineControlPoints = []
|
|
330
|
+
self._arcArrows = []
|
|
331
|
+
|
|
332
|
+
def GetFrom(self):
|
|
333
|
+
"""Get the 'from' object."""
|
|
334
|
+
return self._from
|
|
335
|
+
|
|
336
|
+
def GetTo(self):
|
|
337
|
+
"""Get the 'to' object."""
|
|
338
|
+
return self._to
|
|
339
|
+
|
|
340
|
+
def GetAttachmentFrom(self):
|
|
341
|
+
"""Get the attachment point on the 'from' node."""
|
|
342
|
+
return self._attachmentFrom
|
|
343
|
+
|
|
344
|
+
def GetAttachmentTo(self):
|
|
345
|
+
"""Get the attachment point on the 'to' node."""
|
|
346
|
+
return self._attachmentTo
|
|
347
|
+
|
|
348
|
+
def GetLineControlPoints(self):
|
|
349
|
+
"""Get the line control points."""
|
|
350
|
+
return self._lineControlPoints
|
|
351
|
+
|
|
352
|
+
def SetSpline(self, spline):
|
|
353
|
+
"""Specifies whether a spline is to be drawn through the control points.
|
|
354
|
+
|
|
355
|
+
:param boolean `spline`: True draw a spline through control points.
|
|
356
|
+
|
|
357
|
+
"""
|
|
358
|
+
self._isSpline = spline
|
|
359
|
+
|
|
360
|
+
def IsSpline(self):
|
|
361
|
+
"""If `True` a spline is drawn through the control points."""
|
|
362
|
+
return self._isSpline
|
|
363
|
+
|
|
364
|
+
def SetAttachmentFrom(self, attach):
|
|
365
|
+
"""Set the 'from' shape attachment."""
|
|
366
|
+
self._attachmentFrom = attach
|
|
367
|
+
|
|
368
|
+
def SetAttachmentTo(self, attach):
|
|
369
|
+
"""Set the 'to' shape attachment."""
|
|
370
|
+
self._attachmentTo = attach
|
|
371
|
+
|
|
372
|
+
def Draggable(self):
|
|
373
|
+
"""
|
|
374
|
+
Line is not draggable.
|
|
375
|
+
|
|
376
|
+
:note: This is really to distinguish between lines and other images.
|
|
377
|
+
For lines we want to pass drag to canvas, since lines tend to prevent
|
|
378
|
+
dragging on a canvas (they get in the way.)
|
|
379
|
+
|
|
380
|
+
"""
|
|
381
|
+
return False
|
|
382
|
+
|
|
383
|
+
def SetIgnoreOffsets(self, ignore):
|
|
384
|
+
"""Set whether to ignore offsets from the end of the line when drawing."""
|
|
385
|
+
self._ignoreArrowOffsets = ignore
|
|
386
|
+
|
|
387
|
+
def GetArrows(self):
|
|
388
|
+
"""Get the defined arrows."""
|
|
389
|
+
return self._arcArrows
|
|
390
|
+
|
|
391
|
+
def GetAlignmentStart(self):
|
|
392
|
+
"""Get alignment start"""
|
|
393
|
+
return self._alignmentStart
|
|
394
|
+
|
|
395
|
+
def GetAlignmentEnd(self):
|
|
396
|
+
"""Get alignment end."""
|
|
397
|
+
return self._alignmentEnd
|
|
398
|
+
|
|
399
|
+
def IsEnd(self, nodeObject):
|
|
400
|
+
"""`True` if shape is at the end of the line."""
|
|
401
|
+
return self._to == nodeObject
|
|
402
|
+
|
|
403
|
+
def MakeLineControlPoints(self, n):
|
|
404
|
+
"""
|
|
405
|
+
Make a given number of control points.
|
|
406
|
+
|
|
407
|
+
:param int `n`: number of control points, minimum of two
|
|
408
|
+
|
|
409
|
+
"""
|
|
410
|
+
self._lineControlPoints = []
|
|
411
|
+
|
|
412
|
+
for _ in range(n):
|
|
413
|
+
point = wx.RealPoint(-999, -999)
|
|
414
|
+
self._lineControlPoints.append(point)
|
|
415
|
+
|
|
416
|
+
# pi: added _initialised to keep track of when we have set
|
|
417
|
+
# the middle points to something other than (-999, -999)
|
|
418
|
+
self._initialised = False
|
|
419
|
+
|
|
420
|
+
def InsertLineControlPoint(self, dc = None, point = None):
|
|
421
|
+
"""
|
|
422
|
+
Insert a control point at an optional given position.
|
|
423
|
+
|
|
424
|
+
:param `dc`: an instance of :class:`wx.MemoryDC`
|
|
425
|
+
:param `point`: an optional point, otherwise will use _lineControlPoints
|
|
426
|
+
|
|
427
|
+
"""
|
|
428
|
+
if dc:
|
|
429
|
+
self.Erase(dc)
|
|
430
|
+
|
|
431
|
+
if point:
|
|
432
|
+
line_x, line_y = point
|
|
433
|
+
else:
|
|
434
|
+
last_point = self._lineControlPoints[-1]
|
|
435
|
+
second_last_point = self._lineControlPoints[-2]
|
|
436
|
+
|
|
437
|
+
line_x = (last_point[0] + second_last_point[0]) / 2.0
|
|
438
|
+
line_y = (last_point[1] + second_last_point[1]) / 2.0
|
|
439
|
+
|
|
440
|
+
point = wx.RealPoint(line_x, line_y)
|
|
441
|
+
self._lineControlPoints.insert(len(self._lineControlPoints)-1, point)
|
|
442
|
+
|
|
443
|
+
def DeleteLineControlPoint(self):
|
|
444
|
+
"""Delete an arbitary point on the line."""
|
|
445
|
+
if len(self._lineControlPoints) < 3:
|
|
446
|
+
return False
|
|
447
|
+
|
|
448
|
+
del self._lineControlPoints[-2]
|
|
449
|
+
return True
|
|
450
|
+
|
|
451
|
+
def Initialise(self):
|
|
452
|
+
"""Initialise the line object."""
|
|
453
|
+
if self._lineControlPoints:
|
|
454
|
+
# Just move the first and last control points
|
|
455
|
+
first_point = self._lineControlPoints[0]
|
|
456
|
+
last_point = self._lineControlPoints[-1]
|
|
457
|
+
|
|
458
|
+
# If any of the line points are at -999, we must
|
|
459
|
+
# initialize them by placing them half way between the first
|
|
460
|
+
# and the last.
|
|
461
|
+
|
|
462
|
+
for i in range(1,len(self._lineControlPoints)):
|
|
463
|
+
point = self._lineControlPoints[i]
|
|
464
|
+
if point[0] == -999:
|
|
465
|
+
if first_point[0] < last_point[0]:
|
|
466
|
+
x1 = first_point[0]
|
|
467
|
+
x2 = last_point[0]
|
|
468
|
+
else:
|
|
469
|
+
x2 = first_point[0]
|
|
470
|
+
x1 = last_point[0]
|
|
471
|
+
if first_point[1] < last_point[1]:
|
|
472
|
+
y1 = first_point[1]
|
|
473
|
+
y2 = last_point[1]
|
|
474
|
+
else:
|
|
475
|
+
y2 = first_point[1]
|
|
476
|
+
y1 = last_point[1]
|
|
477
|
+
self._lineControlPoints[i] = wx.RealPoint((x2 - x1) / 2.0 + x1, (y2 - y1) / 2.0 + y1)
|
|
478
|
+
self._initialised = True
|
|
479
|
+
|
|
480
|
+
def FormatText(self, dc, s, i):
|
|
481
|
+
"""
|
|
482
|
+
Format a text string according to the region size, adding
|
|
483
|
+
strings with positions to region text list.
|
|
484
|
+
|
|
485
|
+
:param `dc`: an instance of :class:`wx.MemoryDC`
|
|
486
|
+
:param str `s`: the text string
|
|
487
|
+
:param int `i`: index to the region to be used???
|
|
488
|
+
|
|
489
|
+
"""
|
|
490
|
+
self.ClearText(i)
|
|
491
|
+
|
|
492
|
+
if len(self._regions) == 0 or i >= len(self._regions):
|
|
493
|
+
return
|
|
494
|
+
|
|
495
|
+
region = self._regions[i]
|
|
496
|
+
region.SetText(s)
|
|
497
|
+
dc.SetFont(region.GetFont())
|
|
498
|
+
|
|
499
|
+
w, h = region.GetSize()
|
|
500
|
+
# Initialize the size if zero
|
|
501
|
+
if (w == 0 or h == 0) and s:
|
|
502
|
+
w, h = 100, 50
|
|
503
|
+
region.SetSize(w, h)
|
|
504
|
+
|
|
505
|
+
string_list = FormatText(dc, s, w - 5, h - 5, region.GetFormatMode())
|
|
506
|
+
for s in string_list:
|
|
507
|
+
line = ShapeTextLine(0.0, 0.0, s)
|
|
508
|
+
region.GetFormattedText().append(line)
|
|
509
|
+
|
|
510
|
+
actualW = w
|
|
511
|
+
actualH = h
|
|
512
|
+
if region.GetFormatMode() & FORMAT_SIZE_TO_CONTENTS:
|
|
513
|
+
actualW, actualH = GetCentredTextExtent(dc, region.GetFormattedText(), self._xpos, self._ypos, w, h)
|
|
514
|
+
if actualW != w or actualH != h:
|
|
515
|
+
xx, yy = self.GetLabelPosition(i)
|
|
516
|
+
self.EraseRegion(dc, region, xx, yy)
|
|
517
|
+
if len(self._labelObjects) < i:
|
|
518
|
+
self._labelObjects[i].Select(False, dc)
|
|
519
|
+
self._labelObjects[i].Erase(dc)
|
|
520
|
+
self._labelObjects[i].SetSize(actualW, actualH)
|
|
521
|
+
|
|
522
|
+
region.SetSize(actualW, actualH)
|
|
523
|
+
|
|
524
|
+
if len(self._labelObjects) < i:
|
|
525
|
+
self._labelObjects[i].Select(True, dc)
|
|
526
|
+
self._labelObjects[i].Draw(dc)
|
|
527
|
+
|
|
528
|
+
CentreText(dc, region.GetFormattedText(), self._xpos, self._ypos, actualW, actualH, region.GetFormatMode())
|
|
529
|
+
self._formatted = True
|
|
530
|
+
|
|
531
|
+
def DrawRegion(self, dc, region, x, y):
|
|
532
|
+
"""
|
|
533
|
+
Format one region at this position.
|
|
534
|
+
|
|
535
|
+
:param `dc`: an instance of :class:`wx.MemoryDC`
|
|
536
|
+
:param `dc`: an instance of :class:`~lib.ogl.ShapeRegion`
|
|
537
|
+
:param `x`: the x position
|
|
538
|
+
:param `y`: the y position
|
|
539
|
+
|
|
540
|
+
"""
|
|
541
|
+
if self.GetDisableLabel():
|
|
542
|
+
return
|
|
543
|
+
|
|
544
|
+
w, h = region.GetSize()
|
|
545
|
+
|
|
546
|
+
# Get offset from x, y
|
|
547
|
+
xx, yy = region.GetPosition()
|
|
548
|
+
|
|
549
|
+
xp = xx + x
|
|
550
|
+
yp = yy + y
|
|
551
|
+
|
|
552
|
+
# First, clear a rectangle for the text IF there is any
|
|
553
|
+
if len(region.GetFormattedText()):
|
|
554
|
+
dc.SetPen(self.GetBackgroundPen())
|
|
555
|
+
dc.SetBrush(self.GetBackgroundBrush())
|
|
556
|
+
|
|
557
|
+
# Now draw the text
|
|
558
|
+
if region.GetFont():
|
|
559
|
+
dc.SetFont(region.GetFont())
|
|
560
|
+
dc.DrawRectangle(xp - w / 2.0, yp - h / 2.0, w, h)
|
|
561
|
+
|
|
562
|
+
if self._pen:
|
|
563
|
+
dc.SetPen(self._pen)
|
|
564
|
+
dc.SetTextForeground(region.GetActualColourObject())
|
|
565
|
+
|
|
566
|
+
DrawFormattedText(dc, region.GetFormattedText(), xp, yp, w, h, region.GetFormatMode())
|
|
567
|
+
|
|
568
|
+
def EraseRegion(self, dc, region, x, y):
|
|
569
|
+
"""
|
|
570
|
+
Erase one region at this position.
|
|
571
|
+
|
|
572
|
+
:param `dc`: an instance of :class:`wx.MemoryDC`
|
|
573
|
+
:param `dc`: an instance of :class:`~lib.ogl.ShapeRegion`
|
|
574
|
+
:param `x`: the x position
|
|
575
|
+
:param `y`: the y position
|
|
576
|
+
|
|
577
|
+
"""
|
|
578
|
+
if self.GetDisableLabel():
|
|
579
|
+
return
|
|
580
|
+
|
|
581
|
+
w, h = region.GetSize()
|
|
582
|
+
|
|
583
|
+
# Get offset from x, y
|
|
584
|
+
xx, yy = region.GetPosition()
|
|
585
|
+
|
|
586
|
+
xp = xx + x
|
|
587
|
+
yp = yy + y
|
|
588
|
+
|
|
589
|
+
if region.GetFormattedText():
|
|
590
|
+
dc.SetPen(self.GetBackgroundPen())
|
|
591
|
+
dc.SetBrush(self.GetBackgroundBrush())
|
|
592
|
+
|
|
593
|
+
dc.DrawRectangle(xp - w / 2.0, yp - h / 2.0, w, h)
|
|
594
|
+
|
|
595
|
+
def GetLabelPosition(self, position):
|
|
596
|
+
"""
|
|
597
|
+
Get the reference point for a label.
|
|
598
|
+
|
|
599
|
+
:param `position`: 0 = middle, 1 = start, 2 = end, Region x and y are offsets from this.
|
|
600
|
+
|
|
601
|
+
"""
|
|
602
|
+
if position == 0:
|
|
603
|
+
# Want to take the middle section for the label
|
|
604
|
+
half_way = int(len(self._lineControlPoints) / 2.0)
|
|
605
|
+
|
|
606
|
+
# Find middle of this line
|
|
607
|
+
point = self._lineControlPoints[half_way - 1]
|
|
608
|
+
next_point = self._lineControlPoints[half_way]
|
|
609
|
+
|
|
610
|
+
dx = next_point[0] - point[0]
|
|
611
|
+
dy = next_point[1] - point[1]
|
|
612
|
+
|
|
613
|
+
return point[0] + dx / 2.0, point[1] + dy / 2.0
|
|
614
|
+
elif position == 1:
|
|
615
|
+
return self._lineControlPoints[0][0], self._lineControlPoints[0][1]
|
|
616
|
+
elif position == 2:
|
|
617
|
+
return self._lineControlPoints[-1][0], self._lineControlPoints[-1][1]
|
|
618
|
+
|
|
619
|
+
def Straighten(self, dc = None):
|
|
620
|
+
"""
|
|
621
|
+
Straighten verticals and horizontals.
|
|
622
|
+
|
|
623
|
+
:param `dc`: an instance of :class:`wx.MemoryDC` or None
|
|
624
|
+
|
|
625
|
+
"""
|
|
626
|
+
if len(self._lineControlPoints) < 3:
|
|
627
|
+
return
|
|
628
|
+
|
|
629
|
+
if dc:
|
|
630
|
+
self.Erase(dc)
|
|
631
|
+
|
|
632
|
+
GraphicsStraightenLine(self._lineControlPoints[-1], self._lineControlPoints[-2])
|
|
633
|
+
|
|
634
|
+
for i in range(len(self._lineControlPoints) - 2):
|
|
635
|
+
GraphicsStraightenLine(self._lineControlPoints[i], self._lineControlPoints[i + 1])
|
|
636
|
+
|
|
637
|
+
if dc:
|
|
638
|
+
self.Draw(dc)
|
|
639
|
+
|
|
640
|
+
def Unlink(self):
|
|
641
|
+
"""Unlink the line from the nodes at either end."""
|
|
642
|
+
if self._to:
|
|
643
|
+
self._to.GetLines().remove(self)
|
|
644
|
+
if self._from:
|
|
645
|
+
self._from.GetLines().remove(self)
|
|
646
|
+
self._to = None
|
|
647
|
+
self._from = None
|
|
648
|
+
for i in range(3):
|
|
649
|
+
if self._labelObjects[i]:
|
|
650
|
+
self._labelObjects[i].Select(False)
|
|
651
|
+
self._labelObjects[i].RemoveFromCanvas(self._canvas)
|
|
652
|
+
self.ClearArrowsAtPosition(-1)
|
|
653
|
+
|
|
654
|
+
def Delete(self):
|
|
655
|
+
"""Delete the line, unlink it first."""
|
|
656
|
+
self.Unlink()
|
|
657
|
+
Shape.Delete(self)
|
|
658
|
+
|
|
659
|
+
def SetEnds(self, x1, y1, x2, y2):
|
|
660
|
+
"""
|
|
661
|
+
Set the end positions of the line.
|
|
662
|
+
|
|
663
|
+
:param: `x1`: x1 position
|
|
664
|
+
:param: `y1`: y1 position
|
|
665
|
+
:param: `x2`: x2 position
|
|
666
|
+
:param: `y2`: y2 position
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
"""
|
|
670
|
+
self._lineControlPoints[0] = wx.RealPoint(x1, y1)
|
|
671
|
+
self._lineControlPoints[-1] = wx.RealPoint(x2, y2)
|
|
672
|
+
|
|
673
|
+
# Find centre point
|
|
674
|
+
self._xpos = (x1 + x2) / 2.0
|
|
675
|
+
self._ypos = (y1 + y2) / 2.0
|
|
676
|
+
|
|
677
|
+
# Get absolute positions of ends
|
|
678
|
+
def GetEnds(self):
|
|
679
|
+
"""Get the visible endpoints of the lines for drawing between two objects."""
|
|
680
|
+
first_point = self._lineControlPoints[0]
|
|
681
|
+
last_point = self._lineControlPoints[-1]
|
|
682
|
+
|
|
683
|
+
return first_point[0], first_point[1], last_point[0], last_point[1]
|
|
684
|
+
|
|
685
|
+
def SetAttachments(self, from_attach, to_attach):
|
|
686
|
+
"""
|
|
687
|
+
Specify which object attachment points should be used at each end of the line.
|
|
688
|
+
|
|
689
|
+
:param `from_attach`: the from points ???
|
|
690
|
+
:param `to_attach`: the to points ???
|
|
691
|
+
|
|
692
|
+
"""
|
|
693
|
+
self._attachmentFrom = from_attach
|
|
694
|
+
self._attachmentTo = to_attach
|
|
695
|
+
|
|
696
|
+
def HitTest(self, x, y):
|
|
697
|
+
"""
|
|
698
|
+
Line hit test.
|
|
699
|
+
|
|
700
|
+
:param `x`: x position
|
|
701
|
+
:param `y`: y position
|
|
702
|
+
|
|
703
|
+
"""
|
|
704
|
+
if not self._lineControlPoints:
|
|
705
|
+
return False
|
|
706
|
+
|
|
707
|
+
# Look at label regions in case mouse is over a label
|
|
708
|
+
inLabelRegion = False
|
|
709
|
+
for i in range(3):
|
|
710
|
+
if self._regions[i]:
|
|
711
|
+
region = self._regions[i]
|
|
712
|
+
if len(region._formattedText):
|
|
713
|
+
xp, yp = self.GetLabelPosition(i)
|
|
714
|
+
# Offset region from default label position
|
|
715
|
+
cx, cy = region.GetPosition()
|
|
716
|
+
cw, ch = region.GetSize()
|
|
717
|
+
cx += xp
|
|
718
|
+
cy += yp
|
|
719
|
+
|
|
720
|
+
rLeft = cx - cw / 2.0
|
|
721
|
+
rTop = cy - ch / 2.0
|
|
722
|
+
rRight = cx + cw / 2.0
|
|
723
|
+
rBottom = cy + ch / 2.0
|
|
724
|
+
if x > rLeft and x < rRight and y > rTop and y < rBottom:
|
|
725
|
+
inLabelRegion = True
|
|
726
|
+
break
|
|
727
|
+
|
|
728
|
+
for i in range(len(self._lineControlPoints) - 1):
|
|
729
|
+
point1 = self._lineControlPoints[i]
|
|
730
|
+
point2 = self._lineControlPoints[i + 1]
|
|
731
|
+
|
|
732
|
+
# For inaccurate mousing allow 8 pixel corridor
|
|
733
|
+
extra = 4
|
|
734
|
+
|
|
735
|
+
dx = point2[0] - point1[0]
|
|
736
|
+
dy = point2[1] - point1[1]
|
|
737
|
+
|
|
738
|
+
seg_len = math.sqrt(dx * dx + dy * dy)
|
|
739
|
+
if dy == 0 and dx == 0:
|
|
740
|
+
continue
|
|
741
|
+
distance_from_seg = seg_len * float((x - point1[0]) * dy - (y - point1[1]) * dx) / (dy * dy + dx * dx)
|
|
742
|
+
distance_from_prev = seg_len * float((y - point1[1]) * dy + (x - point1[0]) * dx) / (dy * dy + dx * dx)
|
|
743
|
+
|
|
744
|
+
if abs(distance_from_seg) < extra and distance_from_prev >= 0 and distance_from_prev <= seg_len or inLabelRegion:
|
|
745
|
+
return 0, distance_from_seg
|
|
746
|
+
|
|
747
|
+
return False
|
|
748
|
+
|
|
749
|
+
def DrawArrows(self, dc):
|
|
750
|
+
"""Draw all arrows."""
|
|
751
|
+
# Distance along line of each arrow: space them out evenly
|
|
752
|
+
startArrowPos = 0.0
|
|
753
|
+
endArrowPos = 0.0
|
|
754
|
+
middleArrowPos = 0.0
|
|
755
|
+
|
|
756
|
+
for arrow in self._arcArrows:
|
|
757
|
+
ah = arrow.GetArrowEnd()
|
|
758
|
+
if ah == ARROW_POSITION_START:
|
|
759
|
+
if arrow.GetXOffset() and not self._ignoreArrowOffsets:
|
|
760
|
+
# If specified, x offset is proportional to line length
|
|
761
|
+
self.DrawArrow(dc, arrow, arrow.GetXOffset(), True)
|
|
762
|
+
else:
|
|
763
|
+
self.DrawArrow(dc, arrow, startArrowPos, False)
|
|
764
|
+
startArrowPos += arrow.GetSize() + arrow.GetSpacing()
|
|
765
|
+
elif ah == ARROW_POSITION_END:
|
|
766
|
+
if arrow.GetXOffset() and not self._ignoreArrowOffsets:
|
|
767
|
+
self.DrawArrow(dc, arrow, arrow.GetXOffset(), True)
|
|
768
|
+
else:
|
|
769
|
+
self.DrawArrow(dc, arrow, endArrowPos, False)
|
|
770
|
+
endArrowPos += arrow.GetSize() + arrow.GetSpacing()
|
|
771
|
+
elif ah == ARROW_POSITION_MIDDLE:
|
|
772
|
+
arrow.SetXOffset(middleArrowPos)
|
|
773
|
+
if arrow.GetXOffset() and not self._ignoreArrowOffsets:
|
|
774
|
+
self.DrawArrow(dc, arrow, arrow.GetXOffset(), True)
|
|
775
|
+
else:
|
|
776
|
+
self.DrawArrow(dc, arrow, middleArrowPos, False)
|
|
777
|
+
middleArrowPos += arrow.GetSize() + arrow.GetSpacing()
|
|
778
|
+
|
|
779
|
+
def DrawArrow(self, dc, arrow, XOffset, proportionalOffset):
|
|
780
|
+
"""
|
|
781
|
+
Draw the given arrowhead (or annotation).
|
|
782
|
+
|
|
783
|
+
:param `dc`: an instance of :class:`wx.MemoryDC`
|
|
784
|
+
:param `arrow`: an instannce of :class:`ArrowHead`
|
|
785
|
+
:param `XOffset`: the x offset ???
|
|
786
|
+
:param `proportionalOffset`: ???
|
|
787
|
+
|
|
788
|
+
"""
|
|
789
|
+
first_line_point = self._lineControlPoints[0]
|
|
790
|
+
second_line_point = self._lineControlPoints[1]
|
|
791
|
+
|
|
792
|
+
last_line_point = self._lineControlPoints[-1]
|
|
793
|
+
second_last_line_point = self._lineControlPoints[-2]
|
|
794
|
+
|
|
795
|
+
# Position of start point of line, at the end of which we draw the arrow
|
|
796
|
+
startPositionX, startPositionY = 0.0, 0.0
|
|
797
|
+
|
|
798
|
+
ap = arrow.GetPosition()
|
|
799
|
+
if ap == ARROW_POSITION_START:
|
|
800
|
+
# If we're using a proportional offset, calculate just where this
|
|
801
|
+
# will be on the line.
|
|
802
|
+
realOffset = XOffset
|
|
803
|
+
if proportionalOffset:
|
|
804
|
+
totalLength = math.sqrt((second_line_point[0] - first_line_point[0]) * (second_line_point[0] - first_line_point[0]) + (second_line_point[1] - first_line_point[1]) * (second_line_point[1] - first_line_point[1]))
|
|
805
|
+
realOffset = XOffset * totalLength
|
|
806
|
+
|
|
807
|
+
positionOnLineX, positionOnLineY = GetPointOnLine(second_line_point[0], second_line_point[1], first_line_point[0], first_line_point[1], realOffset)
|
|
808
|
+
|
|
809
|
+
startPositionX = second_line_point[0]
|
|
810
|
+
startPositionY = second_line_point[1]
|
|
811
|
+
elif ap == ARROW_POSITION_END:
|
|
812
|
+
# If we're using a proportional offset, calculate just where this
|
|
813
|
+
# will be on the line.
|
|
814
|
+
realOffset = XOffset
|
|
815
|
+
if proportionalOffset:
|
|
816
|
+
totalLength = math.sqrt((second_last_line_point[0] - last_line_point[0]) * (second_last_line_point[0] - last_line_point[0]) + (second_last_line_point[1] - last_line_point[1]) * (second_last_line_point[1] - last_line_point[1]));
|
|
817
|
+
realOffset = XOffset * totalLength
|
|
818
|
+
|
|
819
|
+
positionOnLineX, positionOnLineY = GetPointOnLine(second_last_line_point[0], second_last_line_point[1], last_line_point[0], last_line_point[1], realOffset)
|
|
820
|
+
|
|
821
|
+
startPositionX = second_last_line_point[0]
|
|
822
|
+
startPositionY = second_last_line_point[1]
|
|
823
|
+
elif ap == ARROW_POSITION_MIDDLE:
|
|
824
|
+
# Choose a point half way between the last and penultimate points
|
|
825
|
+
x = (last_line_point[0] + second_last_line_point[0]) / 2.0
|
|
826
|
+
y = (last_line_point[1] + second_last_line_point[1]) / 2.0
|
|
827
|
+
|
|
828
|
+
# If we're using a proportional offset, calculate just where this
|
|
829
|
+
# will be on the line.
|
|
830
|
+
realOffset = XOffset
|
|
831
|
+
if proportionalOffset:
|
|
832
|
+
totalLength = math.sqrt((second_last_line_point[0] - x) * (second_last_line_point[0] - x) + (second_last_line_point[1] - y) * (second_last_line_point[1] - y));
|
|
833
|
+
realOffset = XOffset * totalLength
|
|
834
|
+
|
|
835
|
+
positionOnLineX, positionOnLineY = GetPointOnLine(second_last_line_point[0], second_last_line_point[1], x, y, realOffset)
|
|
836
|
+
startPositionX = second_last_line_point[0]
|
|
837
|
+
startPositionY = second_last_line_point[1]
|
|
838
|
+
|
|
839
|
+
# Add yOffset to arrow, if any
|
|
840
|
+
|
|
841
|
+
# The translation that the y offset may give
|
|
842
|
+
deltaX = 0.0
|
|
843
|
+
deltaY = 0.0
|
|
844
|
+
if arrow.GetYOffset and not self._ignoreArrowOffsets:
|
|
845
|
+
# |(x4, y4)
|
|
846
|
+
# |d
|
|
847
|
+
# |
|
|
848
|
+
# (x1, y1)--------------(x3, y3)------------------(x2, y2)
|
|
849
|
+
# x4 = x3 - d * math.sin(theta)
|
|
850
|
+
# y4 = y3 + d * math.cos(theta)
|
|
851
|
+
#
|
|
852
|
+
# Where theta = math.tan(-1) of (y3-y1) / (x3-x1)
|
|
853
|
+
x1 = startPositionX
|
|
854
|
+
y1 = startPositionY
|
|
855
|
+
x3 = float(positionOnLineX)
|
|
856
|
+
y3 = float(positionOnLineY)
|
|
857
|
+
d = -arrow.GetYOffset() # Negate so +offset is above line
|
|
858
|
+
|
|
859
|
+
if x3 == x1:
|
|
860
|
+
theta = math.pi / 2.0
|
|
861
|
+
else:
|
|
862
|
+
theta = math.atan((y3 - y1) / (x3 - x1))
|
|
863
|
+
|
|
864
|
+
x4 = x3 - d * math.sin(theta)
|
|
865
|
+
y4 = y3 + d * math.cos(theta)
|
|
866
|
+
|
|
867
|
+
deltaX = x4 - positionOnLineX
|
|
868
|
+
deltaY = y4 - positionOnLineY
|
|
869
|
+
|
|
870
|
+
at = arrow._GetType()
|
|
871
|
+
if at == ARROW_ARROW:
|
|
872
|
+
arrowLength = arrow.GetSize()
|
|
873
|
+
arrowWidth = arrowLength / 3.0
|
|
874
|
+
|
|
875
|
+
tip_x, tip_y, side1_x, side1_y, side2_x, side2_y = GetArrowPoints(startPositionX + deltaX, startPositionY + deltaY, positionOnLineX + deltaX, positionOnLineY + deltaY, arrowLength, arrowWidth)
|
|
876
|
+
|
|
877
|
+
points = [[tip_x, tip_y],
|
|
878
|
+
[side1_x, side1_y],
|
|
879
|
+
[side2_x, side2_y],
|
|
880
|
+
[tip_x, tip_y]]
|
|
881
|
+
|
|
882
|
+
dc.SetPen(self._pen)
|
|
883
|
+
dc.SetBrush(self._brush)
|
|
884
|
+
dc.DrawPolygon(points)
|
|
885
|
+
elif at in [ARROW_HOLLOW_CIRCLE, ARROW_FILLED_CIRCLE]:
|
|
886
|
+
# Find point on line of centre of circle, which is a radius away
|
|
887
|
+
# from the end position
|
|
888
|
+
diameter = arrow.GetSize()
|
|
889
|
+
x, y = GetPointOnLine(startPositionX + deltaX, startPositionY + deltaY,
|
|
890
|
+
positionOnLineX + deltaX, positionOnLineY + deltaY,
|
|
891
|
+
diameter / 2.0)
|
|
892
|
+
x1 = x - diameter / 2.0
|
|
893
|
+
y1 = y - diameter / 2.0
|
|
894
|
+
dc.SetPen(self._pen)
|
|
895
|
+
if arrow._GetType() == ARROW_HOLLOW_CIRCLE:
|
|
896
|
+
dc.SetBrush(self.GetBackgroundBrush())
|
|
897
|
+
else:
|
|
898
|
+
dc.SetBrush(self._brush)
|
|
899
|
+
|
|
900
|
+
dc.DrawEllipse(x1, y1, diameter, diameter)
|
|
901
|
+
elif at == ARROW_SINGLE_OBLIQUE:
|
|
902
|
+
pass
|
|
903
|
+
elif at == ARROW_METAFILE:
|
|
904
|
+
if arrow.GetMetaFile():
|
|
905
|
+
# Find point on line of centre of object, which is a half-width away
|
|
906
|
+
# from the end position
|
|
907
|
+
#
|
|
908
|
+
# width
|
|
909
|
+
# <-- start pos <-----><-- positionOnLineX
|
|
910
|
+
# _____
|
|
911
|
+
# --------------| x | <-- e.g. rectangular arrowhead
|
|
912
|
+
# -----
|
|
913
|
+
#
|
|
914
|
+
x, y = GetPointOnLine(startPositionX, startPositionY,
|
|
915
|
+
positionOnLineX, positionOnLineY,
|
|
916
|
+
arrow.GetMetaFile()._width / 2.0)
|
|
917
|
+
# Calculate theta for rotating the metafile.
|
|
918
|
+
#
|
|
919
|
+
# |
|
|
920
|
+
# | o(x2, y2) 'o' represents the arrowhead.
|
|
921
|
+
# | /
|
|
922
|
+
# | /
|
|
923
|
+
# | /theta
|
|
924
|
+
# | /(x1, y1)
|
|
925
|
+
# |______________________
|
|
926
|
+
#
|
|
927
|
+
x1 = startPositionX
|
|
928
|
+
y1 = startPositionY
|
|
929
|
+
x2 = float(positionOnLineX)
|
|
930
|
+
y2 = float(positionOnLineY)
|
|
931
|
+
|
|
932
|
+
theta = math.atan2(y2 - y1, x2 - x1) % (2 * math.pi)
|
|
933
|
+
|
|
934
|
+
# Rotate about the centre of the object, then place
|
|
935
|
+
# the object on the line.
|
|
936
|
+
if arrow.GetMetaFile().GetRotateable():
|
|
937
|
+
arrow.GetMetaFile().Rotate(0.0, 0.0, theta)
|
|
938
|
+
|
|
939
|
+
if self._erasing:
|
|
940
|
+
# If erasing, just draw a rectangle
|
|
941
|
+
minX, minY, maxX, maxY = arrow.GetMetaFile().GetBounds()
|
|
942
|
+
# Make erasing rectangle slightly bigger or you get droppings
|
|
943
|
+
extraPixels = 4
|
|
944
|
+
dc.DrawRectangle(deltaX + x + minX - extraPixels / 2.0, deltaY + y + minY - extraPixels / 2.0, maxX - minX + extraPixels, maxY - minY + extraPixels)
|
|
945
|
+
else:
|
|
946
|
+
arrow.GetMetaFile().Draw(dc, x + deltaX, y + deltaY)
|
|
947
|
+
|
|
948
|
+
def OnErase(self, dc):
|
|
949
|
+
"""The erase handler."""
|
|
950
|
+
old_pen = self._pen
|
|
951
|
+
old_brush = self._brush
|
|
952
|
+
|
|
953
|
+
bg_pen = self.GetBackgroundPen()
|
|
954
|
+
bg_brush = self.GetBackgroundBrush()
|
|
955
|
+
self.SetPen(bg_pen)
|
|
956
|
+
self.SetBrush(bg_brush)
|
|
957
|
+
|
|
958
|
+
bound_x, bound_y = self.GetBoundingBoxMax()
|
|
959
|
+
if self._font:
|
|
960
|
+
dc.SetFont(self._font)
|
|
961
|
+
|
|
962
|
+
# Undraw text regions
|
|
963
|
+
for i in range(3):
|
|
964
|
+
if self._regions[i]:
|
|
965
|
+
x, y = self.GetLabelPosition(i)
|
|
966
|
+
self.EraseRegion(dc, self._regions[i], x, y)
|
|
967
|
+
|
|
968
|
+
# Undraw line
|
|
969
|
+
dc.SetPen(self.GetBackgroundPen())
|
|
970
|
+
dc.SetBrush(self.GetBackgroundBrush())
|
|
971
|
+
|
|
972
|
+
# Drawing over the line only seems to work if the line has a thickness
|
|
973
|
+
# of 1.
|
|
974
|
+
if old_pen and old_pen.GetWidth() > 1:
|
|
975
|
+
dc.DrawRectangle(self._xpos - bound_x / 2.0 - 2, self._ypos - bound_y / 2.0 - 2,
|
|
976
|
+
bound_x + 4, bound_y + 4)
|
|
977
|
+
else:
|
|
978
|
+
self._erasing = True
|
|
979
|
+
self.GetEventHandler().OnDraw(dc)
|
|
980
|
+
self.GetEventHandler().OnEraseControlPoints(dc)
|
|
981
|
+
self._erasing = False
|
|
982
|
+
|
|
983
|
+
if old_pen:
|
|
984
|
+
self.SetPen(old_pen)
|
|
985
|
+
if old_brush:
|
|
986
|
+
self.SetBrush(old_brush)
|
|
987
|
+
|
|
988
|
+
def GetBoundingBoxMin(self):
|
|
989
|
+
"""Get the minimum bounding box."""
|
|
990
|
+
x1, y1 = 10000, 10000
|
|
991
|
+
x2, y2 = -10000, -10000
|
|
992
|
+
|
|
993
|
+
for point in self._lineControlPoints:
|
|
994
|
+
if point[0] < x1:
|
|
995
|
+
x1 = point[0]
|
|
996
|
+
if point[1] < y1:
|
|
997
|
+
y1 = point[1]
|
|
998
|
+
if point[0] > x2:
|
|
999
|
+
x2 = point[0]
|
|
1000
|
+
if point[1] > y2:
|
|
1001
|
+
y2 = point[1]
|
|
1002
|
+
|
|
1003
|
+
return x2 - x1, y2 - y1
|
|
1004
|
+
|
|
1005
|
+
# For a node image of interest, finds the position of this arc
|
|
1006
|
+
# amongst all the arcs which are attached to THIS SIDE of the node image,
|
|
1007
|
+
# and the number of same.
|
|
1008
|
+
def FindNth(self, image, incoming):
|
|
1009
|
+
"""
|
|
1010
|
+
Find the position of the line on the given object.
|
|
1011
|
+
|
|
1012
|
+
Specify whether incoming or outgoing lines are being considered
|
|
1013
|
+
with incoming.
|
|
1014
|
+
|
|
1015
|
+
:param `image`: a node image
|
|
1016
|
+
:param `incoming`: True to get incoming lines ???
|
|
1017
|
+
|
|
1018
|
+
:returns: nth line, number of lines ???
|
|
1019
|
+
|
|
1020
|
+
"""
|
|
1021
|
+
n = -1
|
|
1022
|
+
num = 0
|
|
1023
|
+
|
|
1024
|
+
if image == self._to:
|
|
1025
|
+
this_attachment = self._attachmentTo
|
|
1026
|
+
else:
|
|
1027
|
+
this_attachment = self._attachmentFrom
|
|
1028
|
+
|
|
1029
|
+
# Find number of lines going into / out of this particular attachment point
|
|
1030
|
+
for line in image.GetLines():
|
|
1031
|
+
if line._from == image:
|
|
1032
|
+
# This is the nth line attached to 'image'
|
|
1033
|
+
if line == self and not incoming:
|
|
1034
|
+
n = num
|
|
1035
|
+
|
|
1036
|
+
# Increment num count if this is the same side (attachment number)
|
|
1037
|
+
if line._attachmentFrom == this_attachment:
|
|
1038
|
+
num += 1
|
|
1039
|
+
|
|
1040
|
+
if line._to == image:
|
|
1041
|
+
# This is the nth line attached to 'image'
|
|
1042
|
+
if line == self and incoming:
|
|
1043
|
+
n = num
|
|
1044
|
+
|
|
1045
|
+
# Increment num count if this is the same side (attachment number)
|
|
1046
|
+
if line._attachmentTo == this_attachment:
|
|
1047
|
+
num += 1
|
|
1048
|
+
|
|
1049
|
+
return n, num
|
|
1050
|
+
|
|
1051
|
+
def OnDrawOutline(self, dc, x, y, w, h):
|
|
1052
|
+
"""The draw outline handler."""
|
|
1053
|
+
old_pen = self._pen
|
|
1054
|
+
old_brush = self._brush
|
|
1055
|
+
|
|
1056
|
+
dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
|
|
1057
|
+
self.SetPen(dottedPen)
|
|
1058
|
+
self.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
1059
|
+
|
|
1060
|
+
self.GetEventHandler().OnDraw(dc)
|
|
1061
|
+
|
|
1062
|
+
if old_pen:
|
|
1063
|
+
self.SetPen(old_pen)
|
|
1064
|
+
else:
|
|
1065
|
+
self.SetPen(None)
|
|
1066
|
+
if old_brush:
|
|
1067
|
+
self.SetBrush(old_brush)
|
|
1068
|
+
else:
|
|
1069
|
+
self.SetBrush(None)
|
|
1070
|
+
|
|
1071
|
+
def OnMovePre(self, dc, x, y, old_x, old_y, display = True):
|
|
1072
|
+
"""The move 'pre' handler. ???"""
|
|
1073
|
+
x_offset = x - old_x
|
|
1074
|
+
y_offset = y - old_y
|
|
1075
|
+
|
|
1076
|
+
if self._lineControlPoints and not (x_offset == 0 and y_offset == 0):
|
|
1077
|
+
for point in self._lineControlPoints:
|
|
1078
|
+
point[0] += x_offset
|
|
1079
|
+
point[1] += y_offset
|
|
1080
|
+
|
|
1081
|
+
# Move temporary label rectangles if necessary
|
|
1082
|
+
for i in range(3):
|
|
1083
|
+
if self._labelObjects[i]:
|
|
1084
|
+
self._labelObjects[i].Erase(dc)
|
|
1085
|
+
xp, yp = self.GetLabelPosition(i)
|
|
1086
|
+
if i < len(self._regions):
|
|
1087
|
+
xr, yr = self._regions[i].GetPosition()
|
|
1088
|
+
else:
|
|
1089
|
+
xr, yr = 0, 0
|
|
1090
|
+
self._labelObjects[i].Move(dc, xp + xr, yp + yr)
|
|
1091
|
+
return True
|
|
1092
|
+
|
|
1093
|
+
def OnMoveLink(self, dc, moveControlPoints = True):
|
|
1094
|
+
"""The move linke handler, called when a connected object has moved, to move the link to
|
|
1095
|
+
correct position.
|
|
1096
|
+
"""
|
|
1097
|
+
if not self._from or not self._to:
|
|
1098
|
+
return
|
|
1099
|
+
|
|
1100
|
+
# Do each end - nothing in the middle. User has to move other points
|
|
1101
|
+
# manually if necessary
|
|
1102
|
+
end_x, end_y, other_end_x, other_end_y = self.FindLineEndPoints()
|
|
1103
|
+
|
|
1104
|
+
oldX, oldY = self._xpos, self._ypos
|
|
1105
|
+
|
|
1106
|
+
# pi: The first time we go through FindLineEndPoints we can't
|
|
1107
|
+
# use the middle points (since they don't have sane values),
|
|
1108
|
+
# so we just do what we do for a normal line. Then we call
|
|
1109
|
+
# Initialise to set the middle points, and then FindLineEndPoints
|
|
1110
|
+
# again, but this time (and from now on) we use the middle
|
|
1111
|
+
# points to calculate the end points.
|
|
1112
|
+
# This was buggy in the C++ version too.
|
|
1113
|
+
|
|
1114
|
+
self.SetEnds(end_x, end_y, other_end_x, other_end_y)
|
|
1115
|
+
|
|
1116
|
+
if len(self._lineControlPoints) > 2:
|
|
1117
|
+
self.Initialise()
|
|
1118
|
+
|
|
1119
|
+
# Do a second time, because one may depend on the other
|
|
1120
|
+
end_x, end_y, other_end_x, other_end_y = self.FindLineEndPoints()
|
|
1121
|
+
self.SetEnds(end_x, end_y, other_end_x, other_end_y)
|
|
1122
|
+
|
|
1123
|
+
# Try to move control points with the arc
|
|
1124
|
+
x_offset = self._xpos - oldX
|
|
1125
|
+
y_offset = self._ypos - oldY
|
|
1126
|
+
|
|
1127
|
+
# Only move control points if it's a self link. And only works
|
|
1128
|
+
# if attachment mode is ON
|
|
1129
|
+
if self._from == self._to and self._from.GetAttachmentMode() != ATTACHMENT_MODE_NONE and moveControlPoints and self._lineControlPoints and not (x_offset == 0 and y_offset == 0):
|
|
1130
|
+
for point in self._lineControlPoints[1:-1]:
|
|
1131
|
+
point[0] += x_offset
|
|
1132
|
+
point[1] += y_offset
|
|
1133
|
+
|
|
1134
|
+
self.Move(dc, self._xpos, self._ypos)
|
|
1135
|
+
|
|
1136
|
+
def FindLineEndPoints(self):
|
|
1137
|
+
"""
|
|
1138
|
+
Finds the x, y points at the two ends of the line.
|
|
1139
|
+
|
|
1140
|
+
This function can be used by e.g. line-routing routines to
|
|
1141
|
+
get the actual points on the two node images where the lines will be
|
|
1142
|
+
drawn to / from.
|
|
1143
|
+
"""
|
|
1144
|
+
if not self._from or not self._to:
|
|
1145
|
+
return
|
|
1146
|
+
|
|
1147
|
+
# Do each end - nothing in the middle. User has to move other points
|
|
1148
|
+
# manually if necessary.
|
|
1149
|
+
second_point = self._lineControlPoints[1]
|
|
1150
|
+
second_last_point = self._lineControlPoints[-2]
|
|
1151
|
+
|
|
1152
|
+
# pi: If we have a segmented line and this is the first time,
|
|
1153
|
+
# do this as a straight line.
|
|
1154
|
+
if len(self._lineControlPoints) > 2 and self._initialised:
|
|
1155
|
+
if self._from.GetAttachmentMode() != ATTACHMENT_MODE_NONE:
|
|
1156
|
+
nth, no_arcs = self.FindNth(self._from, False) # Not incoming
|
|
1157
|
+
end_x, end_y = self._from.GetAttachmentPosition(self._attachmentFrom, nth, no_arcs, self)
|
|
1158
|
+
else:
|
|
1159
|
+
end_x, end_y = self._from.GetPerimeterPoint(self._from.GetX(), self._from.GetY(), second_point[0], second_point[1])
|
|
1160
|
+
|
|
1161
|
+
if self._to.GetAttachmentMode() != ATTACHMENT_MODE_NONE:
|
|
1162
|
+
nth, no_arch = self.FindNth(self._to, True) # Incoming
|
|
1163
|
+
other_end_x, other_end_y = self._to.GetAttachmentPosition(self._attachmentTo, nth, no_arch, self)
|
|
1164
|
+
else:
|
|
1165
|
+
other_end_x, other_end_y = self._to.GetPerimeterPoint(self._to.GetX(), self._to.GetY(), second_last_point[0], second_last_point[1])
|
|
1166
|
+
else:
|
|
1167
|
+
fromX = self._from.GetX()
|
|
1168
|
+
fromY = self._from.GetY()
|
|
1169
|
+
toX = self._to.GetX()
|
|
1170
|
+
toY = self._to.GetY()
|
|
1171
|
+
|
|
1172
|
+
if self._from.GetAttachmentMode() != ATTACHMENT_MODE_NONE:
|
|
1173
|
+
nth, no_arcs = self.FindNth(self._from, False)
|
|
1174
|
+
end_x, end_y = self._from.GetAttachmentPosition(self._attachmentFrom, nth, no_arcs, self)
|
|
1175
|
+
fromX = end_x
|
|
1176
|
+
fromY = end_y
|
|
1177
|
+
|
|
1178
|
+
if self._to.GetAttachmentMode() != ATTACHMENT_MODE_NONE:
|
|
1179
|
+
nth, no_arcs = self.FindNth(self._to, True)
|
|
1180
|
+
other_end_x, other_end_y = self._to.GetAttachmentPosition(self._attachmentTo, nth, no_arcs, self)
|
|
1181
|
+
toX = other_end_x
|
|
1182
|
+
toY = other_end_y
|
|
1183
|
+
|
|
1184
|
+
if self._from.GetAttachmentMode() == ATTACHMENT_MODE_NONE:
|
|
1185
|
+
end_x, end_y = self._from.GetPerimeterPoint(self._from.GetX(), self._from.GetY(), toX, toY)
|
|
1186
|
+
|
|
1187
|
+
if self._to.GetAttachmentMode() == ATTACHMENT_MODE_NONE:
|
|
1188
|
+
other_end_x, other_end_y = self._to.GetPerimeterPoint(self._to.GetX(), self._to.GetY(), fromX, fromY)
|
|
1189
|
+
|
|
1190
|
+
return end_x, end_y, other_end_x, other_end_y
|
|
1191
|
+
|
|
1192
|
+
def OnDraw(self, dc):
|
|
1193
|
+
"""The draw handler."""
|
|
1194
|
+
if not self._lineControlPoints:
|
|
1195
|
+
return
|
|
1196
|
+
|
|
1197
|
+
if self._pen:
|
|
1198
|
+
dc.SetPen(self._pen)
|
|
1199
|
+
if self._brush:
|
|
1200
|
+
dc.SetBrush(self._brush)
|
|
1201
|
+
|
|
1202
|
+
points = []
|
|
1203
|
+
for point in self._lineControlPoints:
|
|
1204
|
+
point = list(map(int, point))
|
|
1205
|
+
points.append(wx.Point(point[0], point[1]))
|
|
1206
|
+
|
|
1207
|
+
if self._isSpline:
|
|
1208
|
+
dc.DrawSpline(points)
|
|
1209
|
+
else:
|
|
1210
|
+
dc.DrawLines(points)
|
|
1211
|
+
|
|
1212
|
+
if sys.platform[:3] == "win":
|
|
1213
|
+
# For some reason, last point isn't drawn under Windows
|
|
1214
|
+
pt = points[-1]
|
|
1215
|
+
dc.DrawPoint(pt[0], pt[1])
|
|
1216
|
+
|
|
1217
|
+
# Problem with pen - if not a solid pen, does strange things
|
|
1218
|
+
# to the arrowhead. So make (get) a new pen that's solid.
|
|
1219
|
+
if self._pen and self._pen.GetStyle() != wx.PENSTYLE_SOLID:
|
|
1220
|
+
solid_pen = wx.Pen(self._pen.GetColour(), 1, wx.PENSTYLE_SOLID)
|
|
1221
|
+
if solid_pen:
|
|
1222
|
+
dc.SetPen(solid_pen)
|
|
1223
|
+
|
|
1224
|
+
self.DrawArrows(dc)
|
|
1225
|
+
|
|
1226
|
+
def OnDrawControlPoints(self, dc):
|
|
1227
|
+
"""The draw control points handler."""
|
|
1228
|
+
if not self._drawHandles:
|
|
1229
|
+
return
|
|
1230
|
+
|
|
1231
|
+
# Draw temporary label rectangles if necessary
|
|
1232
|
+
for i in range(3):
|
|
1233
|
+
if self._labelObjects[i]:
|
|
1234
|
+
self._labelObjects[i].Draw(dc)
|
|
1235
|
+
|
|
1236
|
+
Shape.OnDrawControlPoints(self, dc)
|
|
1237
|
+
|
|
1238
|
+
def OnEraseControlPoints(self, dc):
|
|
1239
|
+
"""The erase control points handler."""
|
|
1240
|
+
# Erase temporary label rectangles if necessary
|
|
1241
|
+
|
|
1242
|
+
for i in range(3):
|
|
1243
|
+
if self._labelObjects[i]:
|
|
1244
|
+
self._labelObjects[i].Erase(dc)
|
|
1245
|
+
|
|
1246
|
+
Shape.OnEraseControlPoints(self, dc)
|
|
1247
|
+
|
|
1248
|
+
def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
|
|
1249
|
+
"""not implemented???"""
|
|
1250
|
+
pass
|
|
1251
|
+
|
|
1252
|
+
def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
1253
|
+
"""not implemented???"""
|
|
1254
|
+
pass
|
|
1255
|
+
|
|
1256
|
+
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
|
|
1257
|
+
"""not implemented???"""
|
|
1258
|
+
pass
|
|
1259
|
+
|
|
1260
|
+
def OnDrawContents(self, dc):
|
|
1261
|
+
"""The draw contents handler."""
|
|
1262
|
+
if self.GetDisableLabel():
|
|
1263
|
+
return
|
|
1264
|
+
|
|
1265
|
+
for i in range(3):
|
|
1266
|
+
if self._regions[i]:
|
|
1267
|
+
x, y = self.GetLabelPosition(i)
|
|
1268
|
+
self.DrawRegion(dc, self._regions[i], x, y)
|
|
1269
|
+
|
|
1270
|
+
def SetTo(self, object):
|
|
1271
|
+
"""Set the 'to' object for the line."""
|
|
1272
|
+
self._to = object
|
|
1273
|
+
|
|
1274
|
+
def SetFrom(self, object):
|
|
1275
|
+
"""Set the 'from' object for the line."""
|
|
1276
|
+
self._from = object
|
|
1277
|
+
|
|
1278
|
+
def MakeControlPoints(self):
|
|
1279
|
+
"""Make handle control points."""
|
|
1280
|
+
if self._canvas and self._lineControlPoints:
|
|
1281
|
+
first = self._lineControlPoints[0]
|
|
1282
|
+
last = self._lineControlPoints[-1]
|
|
1283
|
+
|
|
1284
|
+
control = LineControlPoint(self._canvas, self, CONTROL_POINT_SIZE, first[0], first[1], CONTROL_POINT_ENDPOINT_FROM)
|
|
1285
|
+
control._point = first
|
|
1286
|
+
self._canvas.AddShape(control)
|
|
1287
|
+
self._controlPoints.append(control)
|
|
1288
|
+
|
|
1289
|
+
for point in self._lineControlPoints[1:-1]:
|
|
1290
|
+
control = LineControlPoint(self._canvas, self, CONTROL_POINT_SIZE, point[0], point[1], CONTROL_POINT_LINE)
|
|
1291
|
+
control._point = point
|
|
1292
|
+
self._canvas.AddShape(control)
|
|
1293
|
+
self._controlPoints.append(control)
|
|
1294
|
+
|
|
1295
|
+
control = LineControlPoint(self._canvas, self, CONTROL_POINT_SIZE, last[0], last[1], CONTROL_POINT_ENDPOINT_TO)
|
|
1296
|
+
control._point = last
|
|
1297
|
+
self._canvas.AddShape(control)
|
|
1298
|
+
self._controlPoints.append(control)
|
|
1299
|
+
|
|
1300
|
+
def ResetControlPoints(self):
|
|
1301
|
+
"""Reset the control points."""
|
|
1302
|
+
if self._canvas and self._lineControlPoints and self._controlPoints:
|
|
1303
|
+
for i in range(min(len(self._controlPoints), len(self._lineControlPoints))):
|
|
1304
|
+
point = self._lineControlPoints[i]
|
|
1305
|
+
control = self._controlPoints[i]
|
|
1306
|
+
control.SetX(point[0])
|
|
1307
|
+
control.SetY(point[1])
|
|
1308
|
+
|
|
1309
|
+
def Select(self, select, dc = None):
|
|
1310
|
+
"""Overridden select, to create / delete temporary label-moving objects."""
|
|
1311
|
+
Shape.Select(self, select, dc)
|
|
1312
|
+
if select:
|
|
1313
|
+
for i in range(3):
|
|
1314
|
+
if self._regions[i]:
|
|
1315
|
+
region = self._regions[i]
|
|
1316
|
+
if region._formattedText:
|
|
1317
|
+
w, h = region.GetSize()
|
|
1318
|
+
x, y = region.GetPosition()
|
|
1319
|
+
xx, yy = self.GetLabelPosition(i)
|
|
1320
|
+
|
|
1321
|
+
if self._labelObjects[i]:
|
|
1322
|
+
self._labelObjects[i].Select(False)
|
|
1323
|
+
self._labelObjects[i].RemoveFromCanvas(self._canvas)
|
|
1324
|
+
|
|
1325
|
+
self._labelObjects[i] = self.OnCreateLabelShape(self, region, w, h)
|
|
1326
|
+
self._labelObjects[i].AddToCanvas(self._canvas)
|
|
1327
|
+
self._labelObjects[i].Show(True)
|
|
1328
|
+
if dc:
|
|
1329
|
+
self._labelObjects[i].Move(dc, x + xx, y + yy)
|
|
1330
|
+
self._labelObjects[i].Select(True, dc)
|
|
1331
|
+
else:
|
|
1332
|
+
for i in range(3):
|
|
1333
|
+
if self._labelObjects[i]:
|
|
1334
|
+
self._labelObjects[i].Select(False, dc)
|
|
1335
|
+
self._labelObjects[i].Erase(dc)
|
|
1336
|
+
self._labelObjects[i].RemoveFromCanvas(self._canvas)
|
|
1337
|
+
self._labelObjects[i] = None
|
|
1338
|
+
|
|
1339
|
+
# Control points ('handles') redirect control to the actual shape, to
|
|
1340
|
+
# make it easier to override sizing behaviour.
|
|
1341
|
+
def OnSizingDragLeft(self, pt, draw, x, y, keys = 0, attachment = 0):
|
|
1342
|
+
"""The sizing drag left handler."""
|
|
1343
|
+
dc = wx.MemoryDC()
|
|
1344
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1345
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1346
|
+
dc.SetLogicalFunction(OGLRBLF)
|
|
1347
|
+
|
|
1348
|
+
dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
|
|
1349
|
+
dc.SetPen(dottedPen)
|
|
1350
|
+
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
1351
|
+
|
|
1352
|
+
if pt._type == CONTROL_POINT_LINE:
|
|
1353
|
+
x, y = self._canvas.Snap(x, y)
|
|
1354
|
+
|
|
1355
|
+
pt.SetX(x)
|
|
1356
|
+
pt.SetY(y)
|
|
1357
|
+
pt._point[0] = x
|
|
1358
|
+
pt._point[1] = y
|
|
1359
|
+
|
|
1360
|
+
old_pen = self.GetPen()
|
|
1361
|
+
old_brush = self.GetBrush()
|
|
1362
|
+
|
|
1363
|
+
self.SetPen(dottedPen)
|
|
1364
|
+
self.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
1365
|
+
|
|
1366
|
+
self.GetEventHandler().OnMoveLink(dc, False)
|
|
1367
|
+
|
|
1368
|
+
self.SetPen(old_pen)
|
|
1369
|
+
self.SetBrush(old_brush)
|
|
1370
|
+
|
|
1371
|
+
def OnSizingBeginDragLeft(self, pt, x, y, keys = 0, attachment = 0):
|
|
1372
|
+
"""The sizing begin drag left handler."""
|
|
1373
|
+
dc = wx.MemoryDC()
|
|
1374
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1375
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1376
|
+
|
|
1377
|
+
if pt._type == CONTROL_POINT_LINE:
|
|
1378
|
+
pt._originalPos = pt._point
|
|
1379
|
+
x, y = self._canvas.Snap(x, y)
|
|
1380
|
+
|
|
1381
|
+
self.Erase(dc)
|
|
1382
|
+
|
|
1383
|
+
# Redraw start and end objects because we've left holes
|
|
1384
|
+
# when erasing the line
|
|
1385
|
+
self.GetFrom().OnDraw(dc)
|
|
1386
|
+
self.GetFrom().OnDrawContents(dc)
|
|
1387
|
+
self.GetTo().OnDraw(dc)
|
|
1388
|
+
self.GetTo().OnDrawContents(dc)
|
|
1389
|
+
|
|
1390
|
+
self.SetDisableLabel(True)
|
|
1391
|
+
dc.SetLogicalFunction(OGLRBLF)
|
|
1392
|
+
|
|
1393
|
+
pt._xpos = x
|
|
1394
|
+
pt._ypos = y
|
|
1395
|
+
pt._point[0] = x
|
|
1396
|
+
pt._point[1] = y
|
|
1397
|
+
|
|
1398
|
+
old_pen = self.GetPen()
|
|
1399
|
+
old_brush = self.GetBrush()
|
|
1400
|
+
|
|
1401
|
+
dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
|
|
1402
|
+
self.SetPen(dottedPen)
|
|
1403
|
+
self.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
1404
|
+
|
|
1405
|
+
self.GetEventHandler().OnMoveLink(dc, False)
|
|
1406
|
+
|
|
1407
|
+
self.SetPen(old_pen)
|
|
1408
|
+
self.SetBrush(old_brush)
|
|
1409
|
+
|
|
1410
|
+
if pt._type == CONTROL_POINT_ENDPOINT_FROM or pt._type == CONTROL_POINT_ENDPOINT_TO:
|
|
1411
|
+
self._canvas.SetCursor(wx.Cursor(wx.CURSOR_BULLSEYE))
|
|
1412
|
+
pt._oldCursor = wx.STANDARD_CURSOR
|
|
1413
|
+
|
|
1414
|
+
def OnSizingEndDragLeft(self, pt, x, y, keys = 0, attachment = 0):
|
|
1415
|
+
"""The sizing end drag left handler."""
|
|
1416
|
+
dc = wx.MemoryDC()
|
|
1417
|
+
dc.SelectObject(self.GetCanvas().GetBuffer())
|
|
1418
|
+
self.GetCanvas().PrepareDC(dc)
|
|
1419
|
+
|
|
1420
|
+
self.SetDisableLabel(False)
|
|
1421
|
+
|
|
1422
|
+
if pt._type == CONTROL_POINT_LINE:
|
|
1423
|
+
x, y = self._canvas.Snap(x, y)
|
|
1424
|
+
|
|
1425
|
+
rpt = wx.RealPoint(x, y)
|
|
1426
|
+
|
|
1427
|
+
# Move the control point back to where it was;
|
|
1428
|
+
# MoveControlPoint will move it to the new position
|
|
1429
|
+
# if it decides it wants. We only moved the position
|
|
1430
|
+
# during user feedback so we could redraw the line
|
|
1431
|
+
# as it changed shape.
|
|
1432
|
+
pt._xpos = pt._originalPos[0]
|
|
1433
|
+
pt._ypos = pt._originalPos[1]
|
|
1434
|
+
pt._point[0] = pt._originalPos[0]
|
|
1435
|
+
pt._point[1] = pt._originalPos[1]
|
|
1436
|
+
|
|
1437
|
+
self.OnMoveMiddleControlPoint(dc, pt, rpt)
|
|
1438
|
+
|
|
1439
|
+
if pt._type == CONTROL_POINT_ENDPOINT_FROM:
|
|
1440
|
+
if pt._oldCursor:
|
|
1441
|
+
self._canvas.SetCursor(pt._oldCursor)
|
|
1442
|
+
|
|
1443
|
+
if self.GetFrom():
|
|
1444
|
+
self.GetFrom().MoveLineToNewAttachment(dc, self, x, y)
|
|
1445
|
+
|
|
1446
|
+
if pt._type == CONTROL_POINT_ENDPOINT_TO:
|
|
1447
|
+
if pt._oldCursor:
|
|
1448
|
+
self._canvas.SetCursor(pt._oldCursor)
|
|
1449
|
+
|
|
1450
|
+
if self.GetTo():
|
|
1451
|
+
self.GetTo().MoveLineToNewAttachment(dc, self, x, y)
|
|
1452
|
+
|
|
1453
|
+
# This is called only when a non-end control point is moved
|
|
1454
|
+
def OnMoveMiddleControlPoint(self, dc, lpt, pt):
|
|
1455
|
+
"""The move middle control point handler."""
|
|
1456
|
+
lpt._xpos = pt[0]
|
|
1457
|
+
lpt._ypos = pt[1]
|
|
1458
|
+
|
|
1459
|
+
lpt._point[0] = pt[0]
|
|
1460
|
+
lpt._point[1] = pt[1]
|
|
1461
|
+
|
|
1462
|
+
self.GetEventHandler().OnMoveLink(dc)
|
|
1463
|
+
|
|
1464
|
+
return True
|
|
1465
|
+
|
|
1466
|
+
def AddArrow(self, type, end = ARROW_POSITION_END, size = 10.0, xOffset = 0.0, name = "", mf = None, arrowId = -1):
|
|
1467
|
+
"""
|
|
1468
|
+
Add an arrow (or annotation) to the line.
|
|
1469
|
+
|
|
1470
|
+
:param `type`: an arrow head type, one of the following
|
|
1471
|
+
|
|
1472
|
+
======================================== ==================================
|
|
1473
|
+
Arrow head type Description
|
|
1474
|
+
======================================== ==================================
|
|
1475
|
+
`ARROW_HOLLOW_CIRCLE` a hollow circle
|
|
1476
|
+
`ARROW_FILLED_CIRCLE` a filled circle
|
|
1477
|
+
`ARROW_ARROW` an arrow
|
|
1478
|
+
`ARROW_SINGLE_OBLIQUE` a single oblique
|
|
1479
|
+
`ARROW_DOUBLE_OBLIQUE` a double oblique
|
|
1480
|
+
`ARROW_METAFILE` custom, define in metafile
|
|
1481
|
+
======================================== ==================================
|
|
1482
|
+
|
|
1483
|
+
:param `end`: may be one of the following
|
|
1484
|
+
|
|
1485
|
+
======================================== ==================================
|
|
1486
|
+
Arrow head type Description
|
|
1487
|
+
======================================== ==================================
|
|
1488
|
+
`ARROW_POSITION_END` arrow appears at the end
|
|
1489
|
+
`ARROW_POSITION_START` arrow appears at the start
|
|
1490
|
+
======================================== ==================================
|
|
1491
|
+
|
|
1492
|
+
:param `size`: specifies the lenght of the arrow
|
|
1493
|
+
:param `xOffset`: specifies the offset from the end of the line
|
|
1494
|
+
:param `name`: specifies a name
|
|
1495
|
+
:param `mf`: mf can be a wxPseduoMetaFile, perhaps loaded from a simple Windows
|
|
1496
|
+
metafile.
|
|
1497
|
+
:param `arrowId`: the id for the arrow
|
|
1498
|
+
|
|
1499
|
+
"""
|
|
1500
|
+
arrow = ArrowHead(type, end, size, xOffset, name, mf, arrowId)
|
|
1501
|
+
self._arcArrows.append(arrow)
|
|
1502
|
+
return arrow
|
|
1503
|
+
|
|
1504
|
+
# Add arrowhead at a particular position in the arrowhead list
|
|
1505
|
+
def AddArrowOrdered(self, arrow, referenceList, end):
|
|
1506
|
+
"""
|
|
1507
|
+
Add an arrowhead in the position indicated by the reference list
|
|
1508
|
+
of arrowheads, which contains all legal arrowheads for this line, in
|
|
1509
|
+
the correct order. E.g.
|
|
1510
|
+
|
|
1511
|
+
Reference list: a b c d e
|
|
1512
|
+
Current line list: a d
|
|
1513
|
+
|
|
1514
|
+
Add c, then line list is: a c d.
|
|
1515
|
+
|
|
1516
|
+
If no legal arrowhead position, return FALSE. Assume reference list
|
|
1517
|
+
is for one end only, since it potentially defines the ordering for
|
|
1518
|
+
any one of the 3 positions. So we don't check the reference list for
|
|
1519
|
+
arrowhead position.
|
|
1520
|
+
|
|
1521
|
+
:param `arrow`: an instance of :class:`ArrowHead`
|
|
1522
|
+
:param `referenceList`: ???
|
|
1523
|
+
:param `end`: ???
|
|
1524
|
+
|
|
1525
|
+
"""
|
|
1526
|
+
if not referenceList:
|
|
1527
|
+
return False
|
|
1528
|
+
|
|
1529
|
+
targetName = arrow.GetName()
|
|
1530
|
+
|
|
1531
|
+
# First check whether we need to insert in front of list,
|
|
1532
|
+
# because this arrowhead is the first in the reference
|
|
1533
|
+
# list and should therefore be first in the current list.
|
|
1534
|
+
refArrow = referenceList[0]
|
|
1535
|
+
if refArrow.GetName() == targetName:
|
|
1536
|
+
self._arcArrows.insert(0, arrow)
|
|
1537
|
+
return True
|
|
1538
|
+
|
|
1539
|
+
i1 = i2 = 0
|
|
1540
|
+
while i1 < len(referenceList) and i2 < len(self._arcArrows):
|
|
1541
|
+
refArrow = referenceList[i1]
|
|
1542
|
+
currArrow = self._arcArrows[i2]
|
|
1543
|
+
|
|
1544
|
+
# Matching: advance current arrow pointer
|
|
1545
|
+
if currArrow.GetArrowEnd() == end and currArrow.GetName() == refArrow.GetName():
|
|
1546
|
+
i2 += 1
|
|
1547
|
+
|
|
1548
|
+
# Check if we're at the correct position in the
|
|
1549
|
+
# reference list
|
|
1550
|
+
if targetName == refArrow.GetName():
|
|
1551
|
+
if i2 < len(self._arcArrows):
|
|
1552
|
+
self._arcArrows.insert(i2, arrow)
|
|
1553
|
+
else:
|
|
1554
|
+
self._arcArrows.append(arrow)
|
|
1555
|
+
return True
|
|
1556
|
+
i1 += 1
|
|
1557
|
+
|
|
1558
|
+
self._arcArrows.append(arrow)
|
|
1559
|
+
return True
|
|
1560
|
+
|
|
1561
|
+
def ClearArrowsAtPosition(self, end):
|
|
1562
|
+
"""
|
|
1563
|
+
Delete the arrows at the specified position, or at any position if position is -1.
|
|
1564
|
+
|
|
1565
|
+
:param `end`: position to clear arrow from
|
|
1566
|
+
|
|
1567
|
+
"""
|
|
1568
|
+
if end == -1:
|
|
1569
|
+
self._arcArrows = []
|
|
1570
|
+
return
|
|
1571
|
+
|
|
1572
|
+
for arrow in self._arcArrows:
|
|
1573
|
+
if arrow.GetArrowEnd() == end:
|
|
1574
|
+
self._arcArrows.remove(arrow)
|
|
1575
|
+
|
|
1576
|
+
def ClearArrow(self, name):
|
|
1577
|
+
"""
|
|
1578
|
+
Delete the arrow with the given name.
|
|
1579
|
+
|
|
1580
|
+
:param `name`: name of arrow to delete
|
|
1581
|
+
|
|
1582
|
+
"""
|
|
1583
|
+
for arrow in self._arcArrows:
|
|
1584
|
+
if arrow.GetName() == name:
|
|
1585
|
+
self._arcArrows.remove(arrow)
|
|
1586
|
+
return True
|
|
1587
|
+
return False
|
|
1588
|
+
|
|
1589
|
+
def FindArrowHead(self, position, name):
|
|
1590
|
+
"""
|
|
1591
|
+
Find arrowhead by position and name.
|
|
1592
|
+
|
|
1593
|
+
if position is -1, matches any position.
|
|
1594
|
+
|
|
1595
|
+
:param `position`: position of arrow to find or -1
|
|
1596
|
+
:param `name`: name of arrow to find
|
|
1597
|
+
|
|
1598
|
+
"""
|
|
1599
|
+
for arrow in self._arcArrows:
|
|
1600
|
+
if (position == -1 or position == arrow.GetArrowEnd()) and arrow.GetName() == name:
|
|
1601
|
+
return arrow
|
|
1602
|
+
|
|
1603
|
+
return None
|
|
1604
|
+
|
|
1605
|
+
def FindArrowHeadId(self, arrowId):
|
|
1606
|
+
"""
|
|
1607
|
+
Find arrowhead by id.
|
|
1608
|
+
|
|
1609
|
+
:param `arrowId`: id of arrow to find
|
|
1610
|
+
|
|
1611
|
+
"""
|
|
1612
|
+
for arrow in self._arcArrows:
|
|
1613
|
+
if arrowId == arrow.GetId():
|
|
1614
|
+
return arrow
|
|
1615
|
+
|
|
1616
|
+
return None
|
|
1617
|
+
|
|
1618
|
+
def DeleteArrowHead(self, position, name):
|
|
1619
|
+
"""
|
|
1620
|
+
Delete arrowhead by position and name.
|
|
1621
|
+
|
|
1622
|
+
if position is -1, matches any position.
|
|
1623
|
+
|
|
1624
|
+
:param `position`: position of arrow to delete or -1
|
|
1625
|
+
:param `name`: name of arrow to delete
|
|
1626
|
+
|
|
1627
|
+
"""
|
|
1628
|
+
for arrow in self._arcArrows:
|
|
1629
|
+
if (position == -1 or position == arrow.GetArrowEnd()) and arrow.GetName() == name:
|
|
1630
|
+
self._arcArrows.remove(arrow)
|
|
1631
|
+
return True
|
|
1632
|
+
return False
|
|
1633
|
+
|
|
1634
|
+
def DeleteArrowHeadId(self, arrowId):
|
|
1635
|
+
"""
|
|
1636
|
+
Delete arrowhead by id.
|
|
1637
|
+
|
|
1638
|
+
:param `arrowId`: id of arrow to delete
|
|
1639
|
+
|
|
1640
|
+
"""
|
|
1641
|
+
for arrow in self._arcArrows:
|
|
1642
|
+
if arrowId == arrow.GetId():
|
|
1643
|
+
self._arcArrows.remove(arrow)
|
|
1644
|
+
return True
|
|
1645
|
+
return False
|
|
1646
|
+
|
|
1647
|
+
# Calculate the minimum width a line
|
|
1648
|
+
# occupies, for the purposes of drawing lines in tools.
|
|
1649
|
+
def FindMinimumWidth(self):
|
|
1650
|
+
"""
|
|
1651
|
+
Find the horizontal width for drawing a line with arrows in
|
|
1652
|
+
minimum space. Assume arrows at end only.
|
|
1653
|
+
"""
|
|
1654
|
+
minWidth = 0.0
|
|
1655
|
+
for arrowHead in self._arcArrows:
|
|
1656
|
+
minWidth += arrowHead.GetSize()
|
|
1657
|
+
if arrowHead != self._arcArrows[-1]:
|
|
1658
|
+
minWidth += arrowHead + arrowHead.GetSpacing()
|
|
1659
|
+
|
|
1660
|
+
# We have ABSOLUTE minimum now. So
|
|
1661
|
+
# scale it to give it reasonable aesthetics
|
|
1662
|
+
# when drawing with line.
|
|
1663
|
+
if minWidth > 0:
|
|
1664
|
+
minWidth = minWidth * 1.4
|
|
1665
|
+
else:
|
|
1666
|
+
minWidth = 20.0
|
|
1667
|
+
|
|
1668
|
+
self.SetEnds(0.0, 0.0, minWidth, 0.0)
|
|
1669
|
+
self.Initialise()
|
|
1670
|
+
|
|
1671
|
+
return minWidth
|
|
1672
|
+
|
|
1673
|
+
def FindLinePosition(self, x, y):
|
|
1674
|
+
"""
|
|
1675
|
+
Find which position we're talking about.
|
|
1676
|
+
|
|
1677
|
+
:param `x`: x position
|
|
1678
|
+
:param `y`: y position
|
|
1679
|
+
|
|
1680
|
+
:returns: ARROW_POSITION_START or ARROW_POSITION_MIDDLE or ARROW_POSITION_END.
|
|
1681
|
+
"""
|
|
1682
|
+
startX, startY, endX, endY = self.GetEnds()
|
|
1683
|
+
|
|
1684
|
+
# Find distances from centre, start and end. The smallest wins
|
|
1685
|
+
centreDistance = math.sqrt((x - self._xpos) * (x - self._xpos) + (y - self._ypos) * (y - self._ypos))
|
|
1686
|
+
startDistance = math.sqrt((x - startX) * (x - startX) + (y - startY) * (y - startY))
|
|
1687
|
+
endDistance = math.sqrt((x - endX) * (x - endX) + (y - endY) * (y - endY))
|
|
1688
|
+
|
|
1689
|
+
if centreDistance < startDistance and centreDistance < endDistance:
|
|
1690
|
+
return ARROW_POSITION_MIDDLE
|
|
1691
|
+
elif startDistance < endDistance:
|
|
1692
|
+
return ARROW_POSITION_START
|
|
1693
|
+
else:
|
|
1694
|
+
return ARROW_POSITION_END
|
|
1695
|
+
|
|
1696
|
+
def SetAlignmentOrientation(self, isEnd, isHoriz):
|
|
1697
|
+
"""
|
|
1698
|
+
Set the alignment orientation.
|
|
1699
|
+
|
|
1700
|
+
:param `isEnd`: True or False ???
|
|
1701
|
+
:param `isHoriz`: True of False ???
|
|
1702
|
+
|
|
1703
|
+
"""
|
|
1704
|
+
if isEnd:
|
|
1705
|
+
if isHoriz and self._alignmentEnd & LINE_ALIGNMENT_HORIZ != LINE_ALIGNMENT_HORIZ:
|
|
1706
|
+
self._alignmentEnd != LINE_ALIGNMENT_HORIZ
|
|
1707
|
+
elif not isHoriz and self._alignmentEnd & LINE_ALIGNMENT_HORIZ == LINE_ALIGNMENT_HORIZ:
|
|
1708
|
+
self._alignmentEnd -= LINE_ALIGNMENT_HORIZ
|
|
1709
|
+
else:
|
|
1710
|
+
if isHoriz and self._alignmentStart & LINE_ALIGNMENT_HORIZ != LINE_ALIGNMENT_HORIZ:
|
|
1711
|
+
self._alignmentStart != LINE_ALIGNMENT_HORIZ
|
|
1712
|
+
elif not isHoriz and self._alignmentStart & LINE_ALIGNMENT_HORIZ == LINE_ALIGNMENT_HORIZ:
|
|
1713
|
+
self._alignmentStart -= LINE_ALIGNMENT_HORIZ
|
|
1714
|
+
|
|
1715
|
+
def SetAlignmentType(self, isEnd, alignType):
|
|
1716
|
+
"""
|
|
1717
|
+
Set the alignment type.
|
|
1718
|
+
|
|
1719
|
+
:param `isEnd`: if True set the type for the begin, else for the end ???
|
|
1720
|
+
:param `alignType`: one of the following
|
|
1721
|
+
|
|
1722
|
+
======================================== ==================================
|
|
1723
|
+
Arrow head type Description
|
|
1724
|
+
======================================== ==================================
|
|
1725
|
+
`LINE_ALIGNMENT_HORIZ` Align horizontally
|
|
1726
|
+
`LINE_ALIGNMENT_VERT` Align vertically
|
|
1727
|
+
`LINE_ALIGNMENT_TO_NEXT_HANDLE` Align to next handle
|
|
1728
|
+
`LINE_ALIGNMENT_NONE` vertical by default
|
|
1729
|
+
======================================== ==================================
|
|
1730
|
+
|
|
1731
|
+
"""
|
|
1732
|
+
if isEnd:
|
|
1733
|
+
if alignType == LINE_ALIGNMENT_TO_NEXT_HANDLE:
|
|
1734
|
+
if self._alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE != LINE_ALIGNMENT_TO_NEXT_HANDLE:
|
|
1735
|
+
self._alignmentEnd |= LINE_ALIGNMENT_TO_NEXT_HANDLE
|
|
1736
|
+
elif self._alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE == LINE_ALIGNMENT_TO_NEXT_HANDLE:
|
|
1737
|
+
self._alignmentEnd -= LINE_ALIGNMENT_TO_NEXT_HANDLE
|
|
1738
|
+
else:
|
|
1739
|
+
if alignType == LINE_ALIGNMENT_TO_NEXT_HANDLE:
|
|
1740
|
+
if self._alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE != LINE_ALIGNMENT_TO_NEXT_HANDLE:
|
|
1741
|
+
self._alignmentStart |= LINE_ALIGNMENT_TO_NEXT_HANDLE
|
|
1742
|
+
elif self._alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE == LINE_ALIGNMENT_TO_NEXT_HANDLE:
|
|
1743
|
+
self._alignmentStart -= LINE_ALIGNMENT_TO_NEXT_HANDLE
|
|
1744
|
+
|
|
1745
|
+
def GetAlignmentOrientation(self, isEnd):
|
|
1746
|
+
"""
|
|
1747
|
+
Get the alignment orientation.
|
|
1748
|
+
|
|
1749
|
+
:param `isEnd`: if True get the type for the begin, else for the end ???
|
|
1750
|
+
|
|
1751
|
+
"""
|
|
1752
|
+
if isEnd:
|
|
1753
|
+
return self._alignmentEnd & LINE_ALIGNMENT_HORIZ == LINE_ALIGNMENT_HORIZ
|
|
1754
|
+
else:
|
|
1755
|
+
return self._alignmentStart & LINE_ALIGNMENT_HORIZ == LINE_ALIGNMENT_HORIZ
|
|
1756
|
+
|
|
1757
|
+
def GetAlignmentType(self, isEnd):
|
|
1758
|
+
"""
|
|
1759
|
+
Get the alignment type.
|
|
1760
|
+
|
|
1761
|
+
:param `isEnd`: if True get the type for the begin, else for the end ???
|
|
1762
|
+
|
|
1763
|
+
"""
|
|
1764
|
+
if isEnd:
|
|
1765
|
+
return self._alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE
|
|
1766
|
+
else:
|
|
1767
|
+
return self._alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE
|
|
1768
|
+
|
|
1769
|
+
def GetNextControlPoint(self, shape):
|
|
1770
|
+
"""Find the next control point in the line after the start / end point,
|
|
1771
|
+
depending on whether the shape is at the start or end.
|
|
1772
|
+
|
|
1773
|
+
:param `shape`: an instance of :class:`~lib.ogl.Shape` ???
|
|
1774
|
+
"""
|
|
1775
|
+
n = len(self._lineControlPoints)
|
|
1776
|
+
if self._to == shape:
|
|
1777
|
+
# Must be END of line, so we want (n - 1)th control point.
|
|
1778
|
+
# But indexing ends at n-1, so subtract 2.
|
|
1779
|
+
nn = n - 2
|
|
1780
|
+
else:
|
|
1781
|
+
nn = 1
|
|
1782
|
+
if nn < len(self._lineControlPoints):
|
|
1783
|
+
return self._lineControlPoints[nn]
|
|
1784
|
+
return None
|
|
1785
|
+
|
|
1786
|
+
def OnCreateLabelShape(self, parent, region, w, h):
|
|
1787
|
+
"""Create label shape handler."""
|
|
1788
|
+
return LabelShape(parent, region, w, h)
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
def OnLabelMovePre(self, dc, labelShape, x, y, old_x, old_y, display):
|
|
1792
|
+
"""Label move 'pre' handler. ???"""
|
|
1793
|
+
labelShape._shapeRegion.SetSize(labelShape.GetWidth(), labelShape.GetHeight())
|
|
1794
|
+
|
|
1795
|
+
# Find position in line's region list
|
|
1796
|
+
i = self._regions.index(labelShape._shapeRegion)
|
|
1797
|
+
|
|
1798
|
+
xx, yy = self.GetLabelPosition(i)
|
|
1799
|
+
# Set the region's offset, relative to the default position for
|
|
1800
|
+
# each region.
|
|
1801
|
+
labelShape._shapeRegion.SetPosition(x - xx, y - yy)
|
|
1802
|
+
labelShape.SetX(x)
|
|
1803
|
+
labelShape.SetY(y)
|
|
1804
|
+
|
|
1805
|
+
# Need to reformat to fit region
|
|
1806
|
+
if labelShape._shapeRegion.GetText():
|
|
1807
|
+
s = labelShape._shapeRegion.GetText()
|
|
1808
|
+
labelShape.FormatText(dc, s, i)
|
|
1809
|
+
self.DrawRegion(dc, labelShape._shapeRegion, xx, yy)
|
|
1810
|
+
return True
|
|
1811
|
+
|