|
1 | 1 | // HeeksPython.cpp
|
2 |
| -#include <Python.h> |
3 | 2 | #include "stdafx.h"
|
4 | 3 |
|
5 | 4 | #ifdef WIN32
|
|
10 | 9 | #include "Interface.h"
|
11 | 10 | #include "interface/HeeksCADInterface.h"
|
12 | 11 | #include "interface/HeeksObj.h"
|
| 12 | +#include "interface/ToolImage.h" |
13 | 13 | #include "ConsoleCanvas.h"
|
| 14 | +#include "PythonConfig.h" |
14 | 15 |
|
15 | 16 |
|
16 | 17 |
|
17 | 18 | //#include "src/PointDrawing.h"
|
18 | 19 | #include <set>
|
19 | 20 |
|
20 |
| - |
21 |
| - |
| 21 | +#ifdef _DEBUG |
| 22 | +#undef _DEBUG |
| 23 | +#include <Python.h> |
| 24 | +#include <wx/wxPython/wxPython.h> |
| 25 | +#define _DEBUG |
| 26 | +#else |
| 27 | +#include <Python.h> |
22 | 28 | #include <wx/wxPython/wxPython.h>
|
| 29 | +#endif |
23 | 30 |
|
24 | 31 | extern CHeeksCADInterface *heeksCAD;
|
25 | 32 | extern CHeeksPythonApp *theApp;
|
@@ -733,7 +740,139 @@ static PyObject* NewText(PyObject* self, PyObject* args)
|
733 | 740 | }
|
734 | 741 |
|
735 | 742 |
|
| 743 | +static PyObject* AddMenu(PyObject* self, PyObject* args) |
| 744 | +{ |
| 745 | + const char *menu_name; |
| 746 | + if (!PyArg_ParseTuple(args, "s", &menu_name)) return NULL; |
| 747 | + |
| 748 | + wxFrame* frame = heeksCAD->GetMainFrame(); |
| 749 | + wxMenu *newMenu = new wxMenu; |
| 750 | + frame->GetMenuBar()->Append(newMenu, _U(menu_name)); |
| 751 | + |
| 752 | + return PyInt_FromSize_t((unsigned int)newMenu); |
| 753 | +} |
| 754 | + |
| 755 | +static PyObject* GetFrameHwnd(PyObject* self, PyObject* args) |
| 756 | +{ |
| 757 | + wxFrame* frame = heeksCAD->GetMainFrame(); |
| 758 | + return PyInt_FromSize_t((unsigned int)(frame->GetHWND())); |
| 759 | +} |
| 760 | + |
| 761 | +std::map<int, wxString> menu_item_map; |
| 762 | + |
| 763 | +void OnMenuItem(wxCommandEvent &event) |
| 764 | +{ |
| 765 | + std::map<int, wxString>::iterator FindIt = menu_item_map.find(event.GetId()); |
| 766 | + if(FindIt != menu_item_map.end()) |
| 767 | + { |
| 768 | + // As always, first grab the GIL |
| 769 | + wxPyBlock_t blocked = wxPyBeginBlockThreads(); |
| 770 | + |
| 771 | + // Now make a dictionary to serve as the global namespace when the code is |
| 772 | + // executed. Put a reference to the builtins module in it. (Yes, the |
| 773 | + // names are supposed to be different, I don't know why...) |
| 774 | + PyObject* globals = PyDict_New(); |
| 775 | + PyObject* builtins = PyImport_ImportModule("__builtin__"); |
| 776 | + PyDict_SetItemString(globals, "__builtins__", builtins); |
| 777 | + Py_DECREF(builtins); |
| 778 | + |
| 779 | + // Execute the python code |
| 780 | + std::string _str((const char *) FindIt->second.mb_str(wxConvUTF8)); |
| 781 | + PyObject* result = PyRun_String(_str.c_str(), Py_file_input, globals, globals); |
| 782 | + |
| 783 | + // Release the python objects we still have |
| 784 | + if (result)Py_DECREF(result); |
| 785 | + else PyErr_Print(); |
| 786 | + Py_DECREF(globals); |
| 787 | + |
| 788 | + // Finally, after all Python stuff is done, release the GIL |
| 789 | + wxPyEndBlockThreads(blocked); |
| 790 | + } |
| 791 | +} |
| 792 | + |
| 793 | +static PyObject* AddMenuItem(PyObject* self, PyObject* args) |
| 794 | +{ |
| 795 | + long int_menu; |
| 796 | + const char *title; |
| 797 | + const char *python_script; |
| 798 | + const char *bitmap_path; |
| 799 | + if (!PyArg_ParseTuple(args, "lsss", &int_menu, &title, &python_script, &bitmap_path)) return NULL; |
| 800 | + |
| 801 | + wxMenu *menu = (wxMenu*)int_menu; |
| 802 | + |
| 803 | + int id = heeksCAD->AddMenuItem(menu, wxString(_U(title)), ToolImage(_U(bitmap_path)), OnMenuItem, NULL); |
| 804 | + |
| 805 | + menu_item_map.insert(std::make_pair(id, wxString(_U(python_script)))); |
| 806 | + |
| 807 | + PyObject *pValue = Py_None; |
| 808 | + Py_INCREF(pValue); |
| 809 | + return pValue; |
| 810 | +} |
| 811 | + |
| 812 | +static std::list<wxWindow*> new_windows; |
| 813 | + |
| 814 | +std::map<int, wxWindow*> window_map; |
| 815 | + |
| 816 | +void OnWindow( wxCommandEvent& event ) |
| 817 | +{ |
| 818 | + std::map<int, wxWindow*>::iterator FindIt = window_map.find(event.GetId()); |
| 819 | + if(FindIt != window_map.end()) |
| 820 | + { |
| 821 | + wxWindow* window = FindIt->second; |
| 822 | + wxAuiManager* aui_manager = heeksCAD->GetAuiManager(); |
| 823 | + wxAuiPaneInfo& pane_info = aui_manager->GetPane(window); |
| 824 | + if(pane_info.IsOk()){ |
| 825 | + pane_info.Show(event.IsChecked()); |
| 826 | + aui_manager->Update(); |
| 827 | + } |
| 828 | + } |
| 829 | +} |
| 830 | + |
| 831 | +void OnUpdateWindow( wxUpdateUIEvent& event ) |
| 832 | +{ |
| 833 | + std::map<int, wxWindow*>::iterator FindIt = window_map.find(event.GetId()); |
| 834 | + if(FindIt != window_map.end()) |
| 835 | + { |
| 836 | + wxWindow* window = FindIt->second; |
| 837 | + wxAuiManager* aui_manager = heeksCAD->GetAuiManager(); |
| 838 | + event.Check(aui_manager->GetPane(window).IsShown()); |
| 839 | + } |
| 840 | +} |
| 841 | + |
| 842 | +static PyObject* AddWindow(PyObject* self, PyObject* args) |
| 843 | +{ |
| 844 | + long int_window; |
| 845 | + if (!PyArg_ParseTuple(args, "l", &int_window)) return NULL; |
| 846 | + |
| 847 | + wxFrame* frame = heeksCAD->GetMainFrame(); |
| 848 | + wxAuiManager* aui_manager = heeksCAD->GetAuiManager(); |
| 849 | + |
| 850 | + wxWindow * new_window = new wxWindow(); |
| 851 | + new_window->SetHWND((WXHWND)int_window); |
| 852 | + new_window->AdoptAttributesFromHWND(); |
| 853 | + new_window->Reparent(frame); |
| 854 | + |
| 855 | + wxString label = new_window->GetLabel(); |
| 856 | + |
| 857 | + new_windows.push_back(new_window); |
| 858 | + |
| 859 | + aui_manager->AddPane(new_window, wxAuiPaneInfo().Name(label).Caption(label).Bottom().BestSize(wxSize(600, 200))); |
| 860 | + |
| 861 | + bool window_visible; |
| 862 | + wxString config_name = label + wxString(_T("Visible")); |
| 863 | + PythonConfig config; |
| 864 | + |
| 865 | + config.Read(config_name, &window_visible); |
| 866 | + |
| 867 | + aui_manager->GetPane(new_window).Show(window_visible); |
| 868 | + |
| 869 | + wxMenu* view_menu = heeksCAD->GetWindowMenu(); |
| 870 | + int id = heeksCAD->AddMenuItem(view_menu, label, wxBitmap(), OnWindow, OnUpdateWindow,0,true); |
| 871 | + heeksCAD->RegisterHideableWindow(new_window); |
| 872 | + window_map.insert(std::make_pair(id, new_window)); |
736 | 873 |
|
| 874 | + return PyInt_FromLong(new_window->GetId()); |
| 875 | +} |
737 | 876 |
|
738 | 877 | static PyObject* DXFImport(PyObject* self, PyObject* args)
|
739 | 878 | {
|
@@ -788,6 +927,10 @@ static PyMethodDef HeeksPythonMethods[] = {
|
788 | 927 | {"getpoint" , GetPoint3d, METH_VARARGS, "getpoint()"},
|
789 | 928 | {"addtext", NewText, METH_VARARGS , "addtext('string')"},
|
790 | 929 | {"importdxf", DXFImport, METH_VARARGS , "importdxf('/filepath/filename.dxf')"},
|
| 930 | + {"addmenu", AddMenu, METH_VARARGS , "menu = addmenu('string')"}, |
| 931 | + {"add_menu_item", AddMenuItem, METH_VARARGS , "add_menu_item(menu, 'string', 'python_script')"}, |
| 932 | + {"add_window", AddWindow, METH_VARARGS , "add_window(hwnd)"}, |
| 933 | + {"get_frame_hwnd", GetFrameHwnd, METH_VARARGS , "hwnd = get_frame_hwnd()"}, |
791 | 934 | {NULL, NULL, 0, NULL}
|
792 | 935 | };
|
793 | 936 |
|
|
0 commit comments