Skip to content

Commit 497c86e

Browse files
author
ikrima
committed
FIX: Python Plugin u_function call was not copying output ref params back to python layer
-Adding utility to generate dockable tab spawners as easily as SWindow Extending IStructureDetailsView to python layer -Can now create structure details views. -NOTE: Structs are value types so you may need to copy them back out to the uobjects you bound the detail view to Python plugin layer fix: Copy function params that are const ref arrays back out to python -Other const params don't need to be copied Python Plugin Extensions -Exposing CreateStructureDetailView to Python as separate function -Exposing set_structure_data -Exposing Object Flags & ability to set them to Python to create non RF_Public objects in packages -Exposing ability to pass object flags to new_object Suppress compiler warning for python functions Add py.cmd for executing python commands from console Python Extension: Add ability to grab FBX String property from FBX object Exposed minimize function of SWindow. Exposed SetRealtime function of EditorViewportClient Exposed UActorComponent::GetRootComponent() to python.
1 parent 95259c1 commit 497c86e

16 files changed

+474
-21
lines changed

Source/UnrealEnginePython/Private/Fbx/UEPyFbxProperty.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#if ENGINE_MINOR_VERSION > 12
21
#include "UnrealEnginePythonPrivatePCH.h"
32

3+
#if ENGINE_MINOR_VERSION > 12
44
#if WITH_EDITOR
55

66
#include "UEPyFbx.h"
@@ -14,6 +14,10 @@ static PyObject *py_ue_fbx_property_get_double3(ue_PyFbxProperty *self, PyObject
1414
return Py_BuildValue((char *)"(fff)", value[0], value[1], value[2]);
1515
}
1616

17+
static PyObject *py_ue_fbx_property_get_string(ue_PyFbxProperty *self, PyObject *args) {
18+
return PyUnicode_FromString(self->fbx_property.Get<FbxString>());
19+
}
20+
1721
static PyObject *py_ue_fbx_property_is_valid(ue_PyFbxProperty *self, PyObject *args) {
1822
if (self->fbx_property.IsValid()) {
1923
Py_RETURN_TRUE;
@@ -44,6 +48,7 @@ static PyObject *py_ue_fbx_property_get_curve_node(ue_PyFbxProperty *self, PyObj
4448
static PyMethodDef ue_PyFbxProperty_methods[] = {
4549
{ "get_name", (PyCFunction)py_ue_fbx_property_get_name, METH_VARARGS, "" },
4650
{ "get_double3", (PyCFunction)py_ue_fbx_property_get_double3, METH_VARARGS, "" },
51+
{ "get_string", (PyCFunction)py_ue_fbx_property_get_string, METH_VARARGS, "" },
4752
{ "is_valid", (PyCFunction)py_ue_fbx_property_is_valid, METH_VARARGS, "" },
4853
{ "get_curve_node", (PyCFunction)py_ue_fbx_property_get_curve_node, METH_VARARGS, "" },
4954
{ NULL } /* Sentinel */
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
2+
#include "UnrealEnginePythonPrivatePCH.h"
3+
4+
#if WITH_EDITOR
5+
#include "UEPyIStructureDetailsView.h"
6+
#include "IStructureDetailsView.h"
7+
8+
9+
//#define sw_idetails_view StaticCastSharedRef<IDetailsView>(self->s_compound_widget.s_widget.s_widget)
10+
11+
12+
static PyObject *ue_PyIStructureDetailsView_str(ue_PyIStructureDetailsView *self)
13+
{
14+
#if PY_MAJOR_VERSION >= 3
15+
return PyUnicode_FromFormat("<unreal_engine.%s '%p' (slate ref count: %d, py ref count: %d)>",
16+
TCHAR_TO_UTF8(*self->istructure_details_view->GetWidget()->GetTypeAsString()),
17+
self->istructure_details_view->GetWidget().Get(),
18+
self->istructure_details_view->GetWidget().GetSharedReferenceCount(),
19+
self->ob_base.ob_refcnt);
20+
#else
21+
return PyUnicode_FromFormat("<unreal_engine.%s '%p' (slate ref count: %d)>",
22+
TCHAR_TO_UTF8(*self->istructure_details_view->GetWidget()->GetTypeAsString()),
23+
self->istructure_details_view->GetWidget().Get(),
24+
self->istructure_details_view->GetWidget().GetSharedReferenceCount());
25+
#endif
26+
}
27+
28+
29+
static PyObject *py_ue_istructure_details_view_set_structure_data(ue_PyIStructureDetailsView *self, PyObject * args, PyObject *kwargs)
30+
{
31+
PyObject *py_object = nullptr;
32+
PyObject *py_force_refresh = nullptr;
33+
34+
char *kwlist[] = {
35+
(char *)"struct_data",
36+
(char *)"force_refresh",
37+
nullptr
38+
};
39+
40+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:set_structure_data", kwlist, &py_object, &py_force_refresh))
41+
{
42+
return nullptr;
43+
}
44+
45+
ue_PyUScriptStruct *ue_py_struct = py_ue_is_uscriptstruct(py_object);
46+
if (!ue_py_struct)
47+
{
48+
return PyErr_Format(PyExc_Exception, "argument is not a UScriptStruct");
49+
}
50+
51+
52+
Py_XDECREF(self->ue_py_struct);
53+
self->ue_py_struct = ue_py_struct;
54+
Py_INCREF(self->ue_py_struct);
55+
TSharedPtr<FStructOnScope> struct_scope = MakeShared<FStructOnScope>(ue_py_struct->u_struct, ue_py_struct->data);
56+
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
57+
self->istructure_details_view->SetStructureData(struct_scope);
58+
59+
if (py_force_refresh && PyObject_IsTrue(py_force_refresh))
60+
{
61+
self->istructure_details_view->GetDetailsView().ForceRefresh();
62+
}
63+
64+
Py_RETURN_NONE;
65+
}
66+
67+
static PyObject *py_ue_istructure_details_view_get_widget(ue_PyIStructureDetailsView *self, PyObject * args)
68+
{
69+
if (!self->istructure_details_view.IsValid())
70+
{
71+
return PyErr_Format(PyExc_Exception, "IStructureDetailsView is not valid");
72+
}
73+
74+
TSharedPtr<SWidget> ret_widget = self->istructure_details_view->GetWidget();
75+
if (!ret_widget.IsValid())
76+
{
77+
return PyErr_Format(PyExc_Exception, "unable to create SingleProperty widget");
78+
}
79+
80+
return (PyObject *)py_ue_new_swidget<ue_PySWidget>(ret_widget->AsShared(), &ue_PySWidgetType);
81+
82+
Py_RETURN_NONE;
83+
}
84+
85+
static PyMethodDef ue_PyIStructureDetailsView_methods[] = {
86+
#pragma warning(suppress: 4191)
87+
{ "set_structure_data", (PyCFunction)py_ue_istructure_details_view_set_structure_data, METH_VARARGS | METH_KEYWORDS, "" },
88+
{ "get_widget", (PyCFunction)py_ue_istructure_details_view_get_widget, METH_VARARGS, "" },
89+
{ NULL } /* Sentinel */
90+
};
91+
92+
static void ue_PyIStructureDetailsView_dealloc(ue_PyIStructureDetailsView *self) {
93+
#if defined(UEPY_MEMORY_DEBUG)
94+
UE_LOG(LogPython, Warning, TEXT("Destroying ue_PyIStructureDetailsView %p mapped to IStructureDetailsView %p"), self, &self->istructure_details_view.Get());
95+
#endif
96+
Py_DECREF(self->ue_py_struct);
97+
Py_TYPE(self)->tp_free((PyObject *)self);
98+
}
99+
100+
PyTypeObject ue_PyIStructureDetailsViewType = {
101+
PyVarObject_HEAD_INIT(NULL, 0)
102+
"unreal_engine.IStructureDetailsView", /* tp_name */
103+
sizeof(ue_PyIStructureDetailsView), /* tp_basicsize */
104+
0, /* tp_itemsize */
105+
(destructor)ue_PyIStructureDetailsView_dealloc, /* tp_dealloc */
106+
0, /* tp_print */
107+
0, /* tp_getattr */
108+
0, /* tp_setattr */
109+
0, /* tp_reserved */
110+
0, /* tp_repr */
111+
0, /* tp_as_number */
112+
0, /* tp_as_sequence */
113+
0, /* tp_as_mapping */
114+
0, /* tp_hash */
115+
0, /* tp_call */
116+
(reprfunc)ue_PyIStructureDetailsView_str, /* tp_str */
117+
0, /* tp_getattro */
118+
0, /* tp_setattro */
119+
0, /* tp_as_buffer */
120+
Py_TPFLAGS_DEFAULT, /* tp_flags */
121+
"Unreal Engine IStructureDetailsView", /* tp_doc */
122+
0, /* tp_traverse */
123+
0, /* tp_clear */
124+
0, /* tp_richcompare */
125+
0, /* tp_weaklistoffset */
126+
0, /* tp_iter */
127+
0, /* tp_iternext */
128+
ue_PyIStructureDetailsView_methods, /* tp_methods */
129+
};
130+
131+
static int ue_py_istructure_details_view_init(ue_PyIStructureDetailsView *self, PyObject *args, PyObject *kwargs) {
132+
133+
PyObject *py_object = nullptr;
134+
135+
PyObject *py_allow_search = nullptr;
136+
PyObject *py_update_from_selection = nullptr;
137+
PyObject *py_lockable = nullptr;
138+
char *py_name_area_settings = nullptr;
139+
PyObject *py_hide_selection_tip = nullptr;
140+
PyObject *py_search_initial_key_focus = nullptr;
141+
142+
char *kwlist[] = {
143+
(char*)"struct_data",
144+
(char *)"allow_search",
145+
(char *)"update_from_selection",
146+
(char *)"lockable",
147+
(char *)"name_area_settings",
148+
(char *)"hide_selection_tip",
149+
(char *)"search_initial_key_focus",
150+
nullptr };
151+
152+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOOsOO:__init__", kwlist,
153+
&py_object, &py_allow_search, &py_update_from_selection, &py_lockable, &py_name_area_settings, &py_hide_selection_tip, &py_search_initial_key_focus))
154+
{
155+
return -1;
156+
}
157+
158+
ue_PyUScriptStruct *ue_py_struct = py_ue_is_uscriptstruct(py_object);
159+
if (!ue_py_struct)
160+
{
161+
PyErr_SetString(PyExc_Exception, "argument is not a UScriptStruct");
162+
return -1;
163+
}
164+
165+
FDetailsViewArgs view_args;
166+
view_args.bAllowSearch = (py_allow_search ) ? PyObject_IsTrue(py_allow_search) : view_args.bAllowSearch;
167+
view_args.bUpdatesFromSelection = (py_update_from_selection ) ? PyObject_IsTrue(py_update_from_selection) : view_args.bUpdatesFromSelection;
168+
view_args.bLockable = (py_lockable ) ? PyObject_IsTrue(py_lockable) : view_args.bLockable;
169+
view_args.bHideSelectionTip = (py_hide_selection_tip ) ? PyObject_IsTrue(py_hide_selection_tip) : view_args.bHideSelectionTip;
170+
view_args.bSearchInitialKeyFocus = (py_search_initial_key_focus) ? PyObject_IsTrue(py_search_initial_key_focus) : view_args.bSearchInitialKeyFocus;
171+
172+
FString name_area_string = py_name_area_settings ? FString(UTF8_TO_TCHAR(py_name_area_settings)) : FString();
173+
view_args.NameAreaSettings = [&name_area_string]() {
174+
if (FCString::Stricmp(*name_area_string, TEXT("HideNameArea")) == 0) { return FDetailsViewArgs::ENameAreaSettings::HideNameArea; }
175+
else if (FCString::Stricmp(*name_area_string, TEXT("ObjectsUseNameArea")) == 0) { return FDetailsViewArgs::ENameAreaSettings::ObjectsUseNameArea; }
176+
else if (FCString::Stricmp(*name_area_string, TEXT("ActorsUseNameArea")) == 0) { return FDetailsViewArgs::ENameAreaSettings::ActorsUseNameArea; }
177+
else if (FCString::Stricmp(*name_area_string, TEXT("ComponentsAndActorsUseNameArea")) == 0) { return FDetailsViewArgs::ENameAreaSettings::ComponentsAndActorsUseNameArea; }
178+
else { return FDetailsViewArgs::ENameAreaSettings::ActorsUseNameArea; }
179+
}();
180+
FStructureDetailsViewArgs struct_view_args;
181+
{
182+
struct_view_args.bShowObjects = true;
183+
struct_view_args.bShowAssets = true;
184+
struct_view_args.bShowClasses = true;
185+
struct_view_args.bShowInterfaces = true;
186+
}
187+
new(&self->istructure_details_view) TSharedPtr<IStructureDetailsView>(nullptr);
188+
189+
self->ue_py_struct = ue_py_struct;
190+
Py_INCREF(self->ue_py_struct);
191+
TSharedPtr<FStructOnScope> struct_scope = MakeShared<FStructOnScope>(ue_py_struct->u_struct, ue_py_struct->data);
192+
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
193+
self->istructure_details_view = PropertyEditorModule.CreateStructureDetailView(view_args, struct_view_args, struct_scope);
194+
195+
return 0;
196+
}
197+
198+
void ue_python_init_istructure_details_view(PyObject *ue_module)
199+
{
200+
ue_PyIStructureDetailsViewType.tp_new = PyType_GenericNew;
201+
202+
ue_PyIStructureDetailsViewType.tp_init = (initproc)ue_py_istructure_details_view_init;
203+
204+
ue_PyIStructureDetailsViewType.tp_getattro = PyObject_GenericGetAttr;
205+
ue_PyIStructureDetailsViewType.tp_setattro = PyObject_GenericSetAttr;
206+
207+
if (PyType_Ready(&ue_PyIStructureDetailsViewType) < 0)
208+
return;
209+
210+
Py_INCREF(&ue_PyIStructureDetailsViewType);
211+
PyModule_AddObject(ue_module, "IStructureDetailsView", (PyObject *)&ue_PyIStructureDetailsViewType);
212+
}
213+
214+
ue_PyIStructureDetailsView *py_ue_is_istructure_details_view(PyObject *obj)
215+
{
216+
if (!PyObject_IsInstance(obj, (PyObject *)&ue_PyIStructureDetailsViewType))
217+
return nullptr;
218+
return (ue_PyIStructureDetailsView *)obj;
219+
}
220+
#endif
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include "UnrealEnginePython.h"
4+
5+
#if WITH_EDITOR
6+
typedef struct {
7+
PyObject_HEAD
8+
/* Type-specific fields go here. */
9+
TSharedPtr<IStructureDetailsView> istructure_details_view;
10+
ue_PyUScriptStruct *ue_py_struct;
11+
} ue_PyIStructureDetailsView;
12+
13+
void ue_python_init_istructure_details_view(PyObject *);
14+
15+
ue_PyIStructureDetailsView * py_ue_is_istructure_details_view(PyObject *obj);
16+
17+
#endif

Source/UnrealEnginePython/Private/Slate/UEPySWindow.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ static PyObject *py_ue_swindow_resize(ue_PySWindow *self, PyObject * args)
3939
return (PyObject *)self;
4040
}
4141

42+
static PyObject *py_ue_swindow_minimize(ue_PySWindow *self, PyObject * args)
43+
{
44+
sw_window->Minimize();
45+
46+
Py_INCREF(self);
47+
return (PyObject *)self;
48+
}
49+
4250
static PyObject *py_ue_swindow_set_content(ue_PySWindow *self, PyObject * args)
4351
{
4452
PyObject *py_content;
@@ -130,8 +138,9 @@ static PyObject *py_ue_swindow_add_child(ue_PySWindow *self, PyObject * args)
130138
}
131139

132140
static PyMethodDef ue_PySWindow_methods[] = {
133-
{ "set_title", (PyCFunction)py_ue_swindow_set_title, METH_VARARGS, "" },
134-
{ "set_sizing_rule", (PyCFunction)py_ue_swindow_set_sizing_rule, METH_VARARGS, "" },
141+
{ "set_title", (PyCFunction)py_ue_swindow_set_title, METH_VARARGS, "" },
142+
{ "set_sizing_rule", (PyCFunction)py_ue_swindow_set_sizing_rule, METH_VARARGS, "" },
143+
{ "minimize", (PyCFunction)py_ue_swindow_minimize, METH_VARARGS, "" },
135144
{ "resize", (PyCFunction)py_ue_swindow_resize, METH_VARARGS, "" },
136145
{ "set_client_size", (PyCFunction)py_ue_swindow_resize, METH_VARARGS, "" },
137146
{ "set_content", (PyCFunction)py_ue_swindow_set_content, METH_VARARGS, "" },

0 commit comments

Comments
 (0)