Skip to content

Commit b08942d

Browse files
author
ikrima
committed
Extending SPythonWidget & SPythonListView for fully featured listviews in python
-Add RequestListRefresh to PySlate SListView so we can update listviews without recreating them -Extending get display name to uclass objects -Adding ability to set content to spythonwidget -Adding clear_content ability as well so python defined slate widgets can manipulate their child content slots -Adding find slate style function & find icon for class so we can use built-in style sets -Helper macro to create swidgets with variadic arguments for widgets that need to be constructed with parameters (e.g. tablerow) -FIX: Adding calls to base OnPaint for SPythonWidget and returning the correct layer. Needed so child slot content can draw itself -Adding ability to Set Header Row on SPythonListView -Extending python object of SPythonListView to maintain a reference of items separate from its base .refs field We need to track these separately as we clear the item list on update -Adding generic fslate_style.get() that gets specific widget struct styles from slatestyle set (e.g. combostyle, hyperlink,editabletext,etc) -Also ability to get other style struct types such as slatecolor,fontstyle,slatebrush,etc -Adding parsing margin struct in horizontal box add_slot parsing -Adding get_icon() to fslate_icon struct -FIX: Making uy_PyFSlateIcon carry a value type of FSlateIcon and to use placement new to initialize it -FIX: Crash when OnSelectionChanged is called with null item -Add ability to generate multi column row widgets defined in python -Add ability to set idetails_view object source -Adding a ESlateEnums static class that houses all non-bp based slate enums -Adding options to detail view creation (update from selection, lockable, name_area_settings, etc -Adding EUserInterfaceAction option to menu builder -FIX: FMenuBuilder was not properly being initialized -FIX: SHeaderRow AddColumn was being passed a stack reference variable which was crashing after it went out of scope -Adding python object struct check based on IsChildOf
1 parent caaedb5 commit b08942d

32 files changed

Lines changed: 1106 additions & 93 deletions

‎Source/UnrealEnginePython/Private/Slate/UEPyFMenuBuilder.cpp‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,17 @@ static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyO
4141
char *label;
4242
char *tooltip;
4343
PyObject *py_callable;
44-
PyObject *py_obj = nullptr;
45-
if (!PyArg_ParseTuple(args, "ssO|O:add_menu_entry", &label, &tooltip, &py_callable, &py_obj))
44+
PyObject *py_obj = nullptr;
45+
PyObject *py_uiaction_obj = nullptr;
46+
if (!PyArg_ParseTuple(args, "ssO|OO:add_menu_entry", &label, &tooltip, &py_callable, &py_obj, &py_uiaction_obj))
4647
return nullptr;
4748

4849
if (!PyCallable_Check(py_callable))
4950
{
5051
return PyErr_Format(PyExc_Exception, "argument is not callable");
5152
}
5253

54+
5355
FExecuteAction handler;
5456
UPythonSlateDelegate *py_delegate = NewObject<UPythonSlateDelegate>();
5557
py_delegate->SetPyCallable(py_callable);
@@ -65,7 +67,9 @@ static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyO
6567
handler.BindUObject(py_delegate, &UPythonSlateDelegate::SimpleExecuteAction);
6668
}
6769

68-
self->menu_builder.AddMenuEntry(FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), FSlateIcon(), FUIAction(handler));
70+
ue_PyESlateEnums *py_uiaction_enum = py_uiaction_obj ? py_ue_is_eslate_enums(py_uiaction_obj) : nullptr;
71+
self->menu_builder.AddMenuEntry(FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), FSlateIcon(), FUIAction(handler), NAME_None,
72+
py_uiaction_enum ? (EUserInterfaceActionType::Type)(py_uiaction_enum->val) : EUserInterfaceActionType::Button);
6973

7074
Py_RETURN_NONE;
7175
}
@@ -193,7 +197,7 @@ static PyTypeObject ue_PyFMenuBuilderType = {
193197

194198
static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder *self, PyObject *args, PyObject *kwargs)
195199
{
196-
self->menu_builder = FMenuBuilder(true, nullptr);
200+
new(&self->menu_builder) FMenuBuilder(true, nullptr);
197201
return 0;
198202
}
199203

‎Source/UnrealEnginePython/Private/Slate/UEPyFSlateIcon.cpp‎

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22

33
#include "UEPyFSlateIcon.h"
44

5+
static PyObject *py_ue_fslate_icon_get_icon(ue_PyFSlateIcon *self, PyObject * args)
6+
{
7+
PyObject *ret = py_ue_new_uscriptstruct(FSlateBrush::StaticStruct(), (const uint8*)self->icon.GetIcon());
8+
return ret;
9+
}
10+
511
static PyMethodDef ue_PyFSlateIcon_methods[] = {
12+
{ "get_icon", (PyCFunction)py_ue_fslate_icon_get_icon, METH_VARARGS, "" },
613
{ NULL } /* Sentinel */
714
};
815

916
static PyObject *ue_PyFSlateIcon_str(ue_PyFSlateIcon *self)
1017
{
1118
return PyUnicode_FromFormat("<unreal_engine.SlateIcon {'name': %s}>",
12-
TCHAR_TO_UTF8(*self->icon->GetStyleName().ToString()));
19+
TCHAR_TO_UTF8(*self->icon.GetStyleName().ToString()));
1320
}
1421

1522
static PyTypeObject ue_PyFSlateIconType = {
@@ -55,10 +62,10 @@ static int ue_py_fslate_icon_init(ue_PyFSlateIcon *self, PyObject *args, PyObjec
5562
PyErr_SetString(PyExc_ValueError, "you have not specified as style name");
5663
return -1;
5764
}
58-
self->icon = new FSlateIcon(FName(style_set), FName(style));
65+
new(&self->icon) FSlateIcon(FName(style_set), FName(style));
5966
}
6067
else {
61-
self->icon = new FSlateIcon();
68+
new(&self->icon) FSlateIcon();
6269
}
6370
return 0;
6471
}
@@ -75,8 +82,15 @@ void ue_python_init_fslate_icon(PyObject *ue_module) {
7582
PyModule_AddObject(ue_module, "FSlateIcon", (PyObject *)&ue_PyFSlateIconType);
7683
}
7784

85+
ue_PyFSlateIcon *py_ue_new_fslate_icon(const FSlateIcon slate_icon)
86+
{
87+
ue_PyFSlateIcon *ret = (ue_PyFSlateIcon *)PyObject_New(ue_PyFSlateIcon, &ue_PyFSlateIconType);
88+
ret->icon = slate_icon;
89+
return ret;
90+
}
91+
7892
ue_PyFSlateIcon *py_ue_is_fslate_icon(PyObject *obj) {
79-
if (!PyObject_IsInstance(obj, (PyObject *)&ue_PyFSlateIconType))
80-
return nullptr;
81-
return (ue_PyFSlateIcon *)obj;
93+
if (!PyObject_IsInstance(obj, (PyObject *)&ue_PyFSlateIconType))
94+
return nullptr;
95+
return (ue_PyFSlateIcon *)obj;
8296
}

‎Source/UnrealEnginePython/Private/Slate/UEPyFSlateIcon.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
typedef struct {
88
PyObject_HEAD
99
/* Type-specific fields go here. */
10-
FSlateIcon *icon;
10+
FSlateIcon icon;
1111
} ue_PyFSlateIcon;
1212

1313
void ue_python_init_fslate_icon(PyObject *);
1414

15+
ue_PyFSlateIcon *py_ue_new_fslate_icon(const FSlateIcon slate_icon);
1516
ue_PyFSlateIcon *py_ue_is_fslate_icon(PyObject *);

‎Source/UnrealEnginePython/Private/Slate/UEPyFSlateStyleSet.cpp‎

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "UnrealEnginePythonPrivatePCH.h"
22

33
#include "UEPyFSlateStyleSet.h"
4+
#include "SlateTypes.h"
5+
#include "Map.h"
46

57
static PyObject *py_ue_fslate_style_set_set_content_root(ue_PyFSlateStyleSet *self, PyObject * args)
68
{
@@ -87,9 +89,119 @@ static PyObject *py_ue_fslate_style_set_set(ue_PyFSlateStyleSet *self, PyObject
8789
return PyErr_Format(PyExc_ValueError, "unsupported value type");
8890
}
8991

92+
namespace {
93+
template <typename WidgetStyleType>
94+
PyObject* pyGetWidgetStyle(FSlateStyleSet& InStyle, FName PropertyName)
95+
{
96+
const WidgetStyleType styleWidgetStyle = InStyle.GetWidgetStyle<WidgetStyleType>(PropertyName);
97+
return py_ue_new_uscriptstruct(WidgetStyleType::StaticStruct(), (const uint8*)&styleWidgetStyle);
98+
}
99+
}
100+
101+
static PyObject *py_ue_fslate_style_set_get(ue_PyFSlateStyleSet *self, PyObject * args)
102+
{
103+
if (!(self && self->style_set))
104+
return PyErr_Format(PyExc_Exception, "fstyleset is in invalid state");
105+
106+
char *name = nullptr;
107+
PyObject *py_type = nullptr;
108+
109+
if (!PyArg_ParseTuple(args, "sO:get", &name, &py_type))
110+
return NULL;
111+
112+
PyObject *ret = nullptr;
113+
114+
if (ue_py_check_struct<FSlateSound>(py_type))
115+
{
116+
const FSlateSound& styleSound = self->style_set->GetSound(FName(name));
117+
ret = py_ue_new_uscriptstruct(FSlateSound::StaticStruct(), (const uint8*)&styleSound);
118+
}
119+
else if (ue_py_check_struct<FSlateBrush>(py_type))
120+
{
121+
if (const FSlateBrush* styleBrush = self->style_set->GetBrush(FName(name)))
122+
{
123+
ret = py_ue_new_uscriptstruct(FSlateBrush::StaticStruct(), (const uint8*)styleBrush);
124+
}
125+
}
126+
else if (ue_py_check_struct<FSlateColor>(py_type))
127+
{
128+
const FSlateColor styleSlateColor = self->style_set->GetSlateColor(FName(name));
129+
ret = py_ue_new_uscriptstruct(FSlateColor::StaticStruct(), (const uint8*)&styleSlateColor);
130+
}
131+
else if (ue_py_check_struct<FSlateFontInfo>(py_type))
132+
{
133+
const FSlateFontInfo styleFontInfo = self->style_set->GetFontStyle(FName(name));
134+
ret = py_ue_new_uscriptstruct(FSlateFontInfo::StaticStruct(), (const uint8*)&styleFontInfo);
135+
}
136+
else if (ue_py_check_childstruct<FSlateWidgetStyle>(py_type))
137+
{
138+
typedef TFunction<PyObject* (FSlateStyleSet&, FName)> WStyleGetter;
139+
typedef TPair<UScriptStruct*, WStyleGetter> WStylePair;
140+
static const WStylePair validWidgetStyleUStructList[] = {
141+
WStylePair{ FTextBlockStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FTextBlockStyle> (InStyle, InName); }) },
142+
WStylePair{ FButtonStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FButtonStyle> (InStyle, InName); }) },
143+
WStylePair{ FComboButtonStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FComboButtonStyle> (InStyle, InName); }) },
144+
WStylePair{ FComboBoxStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FComboBoxStyle> (InStyle, InName); }) },
145+
WStylePair{ FHyperlinkStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FHyperlinkStyle> (InStyle, InName); }) },
146+
WStylePair{ FEditableTextStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FEditableTextStyle> (InStyle, InName); }) },
147+
WStylePair{ FScrollBarStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FScrollBarStyle> (InStyle, InName); }) },
148+
WStylePair{ FEditableTextBoxStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FEditableTextBoxStyle> (InStyle, InName); }) },
149+
WStylePair{ FInlineEditableTextBlockStyle::StaticStruct(), WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FInlineEditableTextBlockStyle>(InStyle, InName); }) },
150+
WStylePair{ FProgressBarStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FProgressBarStyle> (InStyle, InName); }) },
151+
WStylePair{ FExpandableAreaStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FExpandableAreaStyle> (InStyle, InName); }) },
152+
WStylePair{ FSearchBoxStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FSearchBoxStyle> (InStyle, InName); }) },
153+
WStylePair{ FSliderStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FSliderStyle> (InStyle, InName); }) },
154+
WStylePair{ FVolumeControlStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FVolumeControlStyle> (InStyle, InName); }) },
155+
WStylePair{ FInlineTextImageStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FInlineTextImageStyle> (InStyle, InName); }) },
156+
WStylePair{ FSpinBoxStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FSpinBoxStyle> (InStyle, InName); }) },
157+
WStylePair{ FSplitterStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FSplitterStyle> (InStyle, InName); }) },
158+
WStylePair{ FTableRowStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FTableRowStyle> (InStyle, InName); }) },
159+
WStylePair{ FTableColumnHeaderStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FTableColumnHeaderStyle> (InStyle, InName); }) },
160+
WStylePair{ FHeaderRowStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FHeaderRowStyle> (InStyle, InName); }) },
161+
WStylePair{ FDockTabStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FDockTabStyle> (InStyle, InName); }) },
162+
WStylePair{ FScrollBoxStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FScrollBoxStyle> (InStyle, InName); }) },
163+
WStylePair{ FScrollBorderStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FScrollBorderStyle> (InStyle, InName); }) },
164+
WStylePair{ FWindowStyle::StaticStruct() , WStyleGetter([](FSlateStyleSet& InStyle, FName InName) { return pyGetWidgetStyle<FWindowStyle> (InStyle, InName); }) },
165+
};
166+
167+
for(WStylePair widgetStyleUStruct : validWidgetStyleUStructList)
168+
{
169+
if (do_ue_py_check_struct(py_type, widgetStyleUStruct.Key))
170+
{
171+
ret = widgetStyleUStruct.Value(*self->style_set, FName(name));
172+
break;
173+
}
174+
}
175+
176+
if (!ret)
177+
{
178+
return PyErr_Format(PyExc_ValueError, "Unsupported FSlateWidgetStyle type. Add it manually.");
179+
}
180+
}
181+
else if (py_ue_is_flinearcolor(py_type))
182+
{
183+
ret = py_ue_new_flinearcolor(self->style_set->GetColor(FName(name)));
184+
}
185+
else if (PyNumber_Check(py_type))
186+
{
187+
ret = PyFloat_FromDouble(self->style_set->GetFloat(FName(name)));
188+
}
189+
else
190+
{
191+
return PyErr_Format(PyExc_ValueError, "unsupported value type");
192+
}
193+
194+
if (!ret)
195+
return PyErr_Format(PyExc_Exception, "Retrieved style object is in invalid state");
196+
197+
return ret;
198+
199+
}
200+
90201
static PyMethodDef ue_PyFSlateStyleSet_methods[] = {
91202
{ "set_content_root", (PyCFunction)py_ue_fslate_style_set_set_content_root, METH_VARARGS, "" },
92203
{ "set", (PyCFunction)py_ue_fslate_style_set_set, METH_VARARGS, "" },
204+
{ "get", (PyCFunction)py_ue_fslate_style_set_get, METH_VARARGS, "" },
93205
{ "register", (PyCFunction)py_ue_fslate_style_set_register, METH_VARARGS, "" },
94206
{ NULL } /* Sentinel */
95207
};
@@ -139,11 +251,18 @@ static int ue_py_fslate_style_set_init(ue_PyFSlateStyleSet *self, PyObject *args
139251
{
140252
return -1;
141253
}
142-
254+
//TODO: roberto: ikrimae- I think this leaks? How is FSlateIcon destroyed ever?
143255
self->style_set = new FSlateStyleSet(name);
144256
return 0;
145257
}
146258

259+
ue_PyFSlateStyleSet* py_ue_new_fslate_style_set(FSlateStyleSet* styleSet)
260+
{
261+
ue_PyFSlateStyleSet *ret = (ue_PyFSlateStyleSet *)PyObject_New(ue_PyFSlateStyleSet, &ue_PyFSlateStyleSetType);
262+
ret->style_set = styleSet;
263+
return ret;
264+
}
265+
147266
void ue_python_init_fslate_style_set(PyObject *ue_module)
148267
{
149268
ue_PyFSlateStyleSetType.tp_new = PyType_GenericNew;

‎Source/UnrealEnginePython/Private/Slate/UEPyFSlateStyleSet.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
#include "UnrealEnginePython.h"
44

5-
#include "Runtime/SlateCore/Public/Styling/SlateStyle.h"
6-
75
typedef struct {
86
PyObject_HEAD
97
/* Type-specific fields go here. */
108
FSlateStyleSet *style_set;
119
} ue_PyFSlateStyleSet;
1210

11+
ue_PyFSlateStyleSet* py_ue_new_fslate_style_set(FSlateStyleSet* styleSet);
12+
1313
void ue_python_init_fslate_style_set(PyObject *);

‎Source/UnrealEnginePython/Private/Slate/UEPyFToolBarBuilder.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static PyObject *py_ue_ftool_bar_builder_add_tool_bar_button(ue_PyFToolBarBuilde
5454
handler.BindUObject(py_delegate, &UPythonSlateDelegate::SimpleExecuteAction);
5555
}
5656

57-
self->tool_bar_builder.AddToolBarButton(FUIAction(handler), FName(hook), FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), *py_slate_icon->icon);
57+
self->tool_bar_builder.AddToolBarButton(FUIAction(handler), FName(hook), FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), py_slate_icon->icon);
5858

5959
Py_INCREF(Py_None);
6060
return Py_None;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
2+
#include "UnrealEnginePythonPrivatePCH.h"
3+
4+
#if WITH_EDITOR
5+
6+
#include "Editor/PropertyEditor/Public/IDetailsView.h"
7+
8+
#include "UEPyIDetailsView.h"
9+
10+
11+
#define sw_idetails_view StaticCastSharedRef<IDetailsView>(self->s_compound_widget.s_widget.s_widget)
12+
13+
static PyObject *py_ue_idetails_view_set_object(ue_PyIDetailsView *self, PyObject * args, PyObject *kwargs)
14+
{
15+
PyObject *py_in_obj = nullptr;
16+
PyObject *py_force_refresh = nullptr;
17+
18+
char *kwlist[] = {
19+
(char *)"uobject",
20+
(char *)"force_refresh",
21+
nullptr
22+
};
23+
24+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:set_object", kwlist, &py_in_obj, &py_force_refresh))
25+
{
26+
return nullptr;
27+
}
28+
29+
UObject *u_object = ue_py_check_type<UObject>(py_in_obj);
30+
if (!u_object)
31+
{
32+
return PyErr_Format(PyExc_Exception, "argument is not a UObject");
33+
}
34+
35+
const bool bForceRefresh = py_force_refresh && PyObject_IsTrue(py_force_refresh);
36+
37+
sw_idetails_view->SetObject(u_object, bForceRefresh);
38+
39+
Py_RETURN_NONE;
40+
}
41+
42+
static PyMethodDef ue_PyIDetailsView_methods[] = {
43+
#pragma warning(suppress: 4191)
44+
{ "set_object", (PyCFunction)py_ue_idetails_view_set_object, METH_VARARGS | METH_KEYWORDS, "" },
45+
{ NULL } /* Sentinel */
46+
};
47+
48+
PyTypeObject ue_PyIDetailsViewType = {
49+
PyVarObject_HEAD_INIT(NULL, 0)
50+
"unreal_engine.IDetailsView", /* tp_name */
51+
sizeof(ue_PyIDetailsView), /* tp_basicsize */
52+
0, /* tp_itemsize */
53+
0, /* tp_dealloc */
54+
0, /* tp_print */
55+
0, /* tp_getattr */
56+
0, /* tp_setattr */
57+
0, /* tp_reserved */
58+
0, /* tp_repr */
59+
0, /* tp_as_number */
60+
0, /* tp_as_sequence */
61+
0, /* tp_as_mapping */
62+
0, /* tp_hash */
63+
0, /* tp_call */
64+
0, /* tp_str */
65+
0, /* tp_getattro */
66+
0, /* tp_setattro */
67+
0, /* tp_as_buffer */
68+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
69+
"Unreal Engine IDetailsView", /* tp_doc */
70+
0, /* tp_traverse */
71+
0, /* tp_clear */
72+
0, /* tp_richcompare */
73+
0, /* tp_weaklistoffset */
74+
0, /* tp_iter */
75+
0, /* tp_iternext */
76+
ue_PyIDetailsView_methods, /* tp_methods */
77+
};
78+
79+
void ue_python_init_idetails_view(PyObject *ue_module)
80+
{
81+
ue_PyIDetailsViewType.tp_base = &ue_PySCompoundWidgetType;
82+
83+
if (PyType_Ready(&ue_PyIDetailsViewType) < 0)
84+
return;
85+
86+
Py_INCREF(&ue_PyIDetailsViewType);
87+
PyModule_AddObject(ue_module, "IDetailsView", (PyObject *)&ue_PyIDetailsViewType);
88+
}
89+
90+
ue_PyIDetailsView *py_ue_is_idetails_view(PyObject *obj)
91+
{
92+
if (!PyObject_IsInstance(obj, (PyObject *)&ue_PyIDetailsViewType))
93+
return nullptr;
94+
return (ue_PyIDetailsView *)obj;
95+
}
96+
#endif
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
#include "UnrealEnginePython.h"
4+
5+
#if WITH_EDITOR
6+
#include "UEPySCompoundWidget.h"
7+
8+
extern PyTypeObject ue_PySCompoundWidgetType;
9+
10+
typedef struct {
11+
ue_PySCompoundWidget s_compound_widget;
12+
/* Type-specific fields go here. */
13+
} ue_PyIDetailsView;
14+
15+
void ue_python_init_idetails_view(PyObject *);
16+
17+
ue_PyIDetailsView * py_ue_is_idetails_view(PyObject *obj);
18+
19+
#endif

0 commit comments

Comments
 (0)