Skip to content

Commit 51dbf7e

Browse files
author
ikrima
committed
ListView & Header Row extensions & fixes
-Add filtering to py listviews, fixing column adjustments, adding sorting -FIX: Py Widget Visibility set properly now -FIX: Python header row in listview properly initialized as part of widget declaration so SListView construct() call properly initializes header related artifacts -Extending header row with more attributes like label,tooltip,align,width,fill,sort mode, etc -Adding string from args optional macro define -Adding get bp hierarchy from actor class & get all graphs out of a blueprint and ability to show settings
1 parent b2ba293 commit 51dbf7e

8 files changed

Lines changed: 202 additions & 77 deletions

File tree

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

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,54 @@
44

55
#define sw_header_row StaticCastSharedRef<SHeaderRow>(self->s_border.s_compound_widget.s_widget.s_widget)
66

7-
static PyObject *py_ue_sheader_row_add_column(ue_PySHeaderRow *self, PyObject *args, PyObject *kwargs) {
8-
9-
char *column_id;
10-
float fixed_width = 0;
11-
int cell_h_align = 0;
12-
int cell_v_align = 0;
13-
char *default_label = nullptr;
14-
char *default_tooltip = nullptr;
15-
16-
char *kwlist[] = {
17-
(char *)"column_id",
18-
(char *)"fixed_width",
19-
(char *)"cell_h_align",
20-
(char *)"cell_v_align",
21-
(char *)"default_label",
22-
(char *)"default_tooltip",
23-
nullptr
24-
};
25-
26-
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sf|iiss:add_column", kwlist,
27-
&column_id,
28-
&fixed_width,
29-
&cell_h_align,
30-
&cell_v_align,
31-
&default_label,
32-
&default_tooltip)) {
33-
return NULL;
34-
}
35-
36-
if (!default_label)
37-
default_label = column_id;
38-
39-
if (!default_tooltip)
40-
default_tooltip = default_label;
41-
42-
sw_header_row->AddColumn(
43-
SHeaderRow::Column(FName(UTF8_TO_TCHAR(column_id)))
44-
.DefaultLabel(FText::FromString(UTF8_TO_TCHAR(default_label)))
45-
.DefaultTooltip(FText::FromString(UTF8_TO_TCHAR(default_tooltip)))
46-
.FixedWidth(fixed_width)
47-
.HAlignCell((EHorizontalAlignment)cell_h_align)
48-
.VAlignCell((EVerticalAlignment)cell_v_align)
49-
);
7+
static PyObject *py_ue_sheader_row_add_column(ue_PySHeaderRow *self, PyObject *args, PyObject *kwargs)
8+
{
9+
int32 retCode = [&]() {
10+
ue_py_slate_setup_farguments(SHeaderRow::FColumn);
11+
12+
// first of all check for values
13+
PyObject *py_columnid = ue_py_dict_get_item(kwargs, "column_id");
14+
if (!py_columnid) {
15+
PyErr_SetString(PyExc_TypeError, "you must specify the column_id");
16+
return -1;
17+
}
18+
19+
ue_py_slate_farguments_optional_string("column_id", ColumnId);
20+
21+
ue_py_slate_farguments_optional_text("default_label", DefaultLabel);
22+
ue_py_slate_farguments_optional_text("default_tooltip", DefaultTooltip);
23+
24+
ue_py_slate_farguments_optional_enum("h_align_header", HAlignHeader, EHorizontalAlignment);
25+
ue_py_slate_farguments_optional_enum("v_align_header", VAlignHeader, EVerticalAlignment);
26+
27+
ue_py_slate_farguments_optional_float("fill_width", FillWidth);
28+
ue_py_slate_farguments_optional_float("fixed_width", FixedWidth);
29+
30+
ue_py_slate_farguments_optional_enum("h_align_cell", HAlignCell, EHorizontalAlignment);
31+
ue_py_slate_farguments_optional_enum("v_align_cell", VAlignCell, EVerticalAlignment);
32+
33+
ue_py_slate_farguments_optional_enum("sort_mode", SortMode, EColumnSortMode::Type);
34+
ue_py_slate_farguments_optional_enum("sort_priority", SortPriority, EColumnSortPriority::Type);
35+
36+
ue_py_slate_farguments_event("on_sort", OnSort, FOnSortModeChanged, OnSort);
37+
38+
//sw_header_row->AddColumn(
39+
// SHeaderRow::Column(FName(UTF8_TO_TCHAR(column_id)))
40+
// .DefaultLabel(FText::FromString(UTF8_TO_TCHAR(default_label)))
41+
// .DefaultTooltip(FText::FromString(UTF8_TO_TCHAR(default_tooltip)))
42+
// .FixedWidth(fixed_width)
43+
// .HAlignCell((EHorizontalAlignment)cell_h_align)
44+
// .VAlignCell((EVerticalAlignment)cell_v_align)
45+
//);
46+
47+
sw_header_row->AddColumn(arguments);
48+
return 0;
49+
}();
50+
51+
if (retCode != 0)
52+
{
53+
return PyErr_Format(PyExc_Exception, "could not add column slot");
54+
}
5055

5156
Py_INCREF(self);
5257
return (PyObject *)self;

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,22 @@ static int ue_py_spython_list_view_init(ue_PySPythonListView *self, PyObject *ar
169169
}
170170
arguments.ListItemsSource(&self->item_source_list);
171171

172+
{
173+
PyObject *value = ue_py_dict_get_item(kwargs, "header_row");
174+
if (value) {
175+
if (ue_PySHeaderRow *_py_swidget = py_ue_is_sheader_row(value)) {
176+
177+
Py_INCREF(_py_swidget);
178+
((ue_PySWidget *)self)->py_refs.Add(value);
179+
arguments.HeaderRow(StaticCastSharedRef<SHeaderRow>(((ue_PySWidget *)_py_swidget)->s_widget));
180+
}
181+
else {
182+
PyErr_SetString(PyExc_TypeError, "unsupported type for attribute " "header_row");
183+
return -1;
184+
}
185+
}
186+
}
187+
172188
ue_py_slate_farguments_optional_enum("allow_overscroll", AllowOverscroll, EAllowOverscroll);
173189
ue_py_slate_farguments_optional_bool("clear_selection_on_click", ClearSelectionOnClick);
174190
ue_py_slate_farguments_optional_enum("consume_mouse_wheel", ConsumeMouseWheel, EConsumeMouseWheel);

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,42 @@ static PyObject *py_ue_swidget_get_children(ue_PySWidget *self, PyObject * args)
3030

3131
static PyObject *py_ue_swidget_set_visibility(ue_PySWidget *self, PyObject * args)
3232
{
33-
int visibility;
34-
if (!PyArg_ParseTuple(args, "i:set_visibility", &visibility))
33+
PyObject* py_object;
34+
if (!PyArg_ParseTuple(args, "O:set_visibility", &py_object))
3535
{
3636
return nullptr;
3737
}
3838

39-
self->s_widget->SetVisibility(EVisibility::Visible);
39+
if (!PyNumber_Check(py_object))
40+
{
41+
return PyErr_Format(PyExc_Exception, "argument is not a ESlateVisibility");
42+
}
43+
44+
PyObject *py_value = PyNumber_Long(py_object);
45+
ESlateVisibility slateVisibility = (ESlateVisibility)PyLong_AsLong(py_value);
46+
Py_DECREF(py_value);
47+
48+
EVisibility visibility;
49+
switch (slateVisibility)
50+
{
51+
case ESlateVisibility::Visible:
52+
visibility = EVisibility::Visible;
53+
break;
54+
case ESlateVisibility::Collapsed:
55+
visibility = EVisibility::Collapsed;
56+
break;
57+
case ESlateVisibility::Hidden:
58+
visibility = EVisibility::Hidden;
59+
break;
60+
case ESlateVisibility::HitTestInvisible:
61+
visibility = EVisibility::HitTestInvisible;
62+
break;
63+
case ESlateVisibility::SelfHitTestInvisible:
64+
visibility = EVisibility::SelfHitTestInvisible;
65+
break;
66+
}
67+
68+
self->s_widget->SetVisibility(visibility);
4069

4170
Py_INCREF(self);
4271
return (PyObject *)self;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,19 @@ void UPythonSlateDelegate::OnFloatCommitted(float value, ETextCommit::Type commi
176176
Py_DECREF(ret);
177177
}
178178

179+
void UPythonSlateDelegate::OnSort(const EColumnSortPriority::Type SortPriority, const FName& ColumnName, const EColumnSortMode::Type NewSortMode)
180+
{
181+
FScopePythonGIL gil;
182+
183+
PyObject *ret = PyObject_CallFunction(py_callable, (char *)"isi", (int)SortPriority, TCHAR_TO_UTF8(*ColumnName.ToString()), (int)NewSortMode);
184+
if (!ret)
185+
{
186+
unreal_engine_py_log_error();
187+
return;
188+
}
189+
Py_DECREF(ret);
190+
}
191+
179192
void UPythonSlateDelegate::CheckBoxChanged(ECheckBoxState state)
180193
{
181194
FScopePythonGIL gil;

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,12 @@ ue_PySWidget *ue_py_get_swidget(TSharedRef<SWidget> s_widget);
375375
}\
376376
}
377377

378+
#define ue_py_slate_farguments_optional_string(param, attribute) { PyObject *value = ue_py_dict_get_item(kwargs, param);\
379+
if (PyUnicode_Check(value)) {\
380+
arguments.attribute(UTF8_TO_TCHAR(PyUnicode_AsUTF8(value)));\
381+
}\
382+
}
383+
378384
#define ue_py_slate_farguments_optional_text(param, attribute) { PyObject *value = ue_py_dict_get_item(kwargs, param);\
379385
if (value) {\
380386
if (PyUnicode_Check(value)) {\
@@ -449,6 +455,7 @@ class UPythonSlateDelegate : public UPythonDelegate
449455
void OnTextCommitted(const FText &text, ETextCommit::Type commit_type);
450456
void OnFloatChanged(float value);
451457
void OnFloatCommitted(float value, ETextCommit::Type commit_type);
458+
void OnSort(const EColumnSortPriority::Type SortPriority, const FName& ColumnName, const EColumnSortMode::Type NewSortMode);
452459

453460
void OnLinearColorChanged(FLinearColor color);
454461

‎Source/UnrealEnginePython/Private/UEPyEditor.cpp‎

Lines changed: 78 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "Editor/LandscapeEditor/Public/LandscapeFileFormatInterface.h"
2727

2828
#include "Developer/Settings/Public/ISettingsModule.h"
29+
#include "Engine/Blueprint.h"
2930

3031

3132
PyObject *py_unreal_engine_editor_play_in_viewport(PyObject * self, PyObject * args)
@@ -1120,6 +1121,33 @@ PyObject *py_unreal_engine_create_blueprint(PyObject * self, PyObject * args)
11201121

11211122
}
11221123

1124+
PyObject *py_unreal_engine_get_blueprint_hierarchy_from_class(PyObject * self, PyObject * args)
1125+
{
1126+
PyObject *py_class;
1127+
if (!PyArg_ParseTuple(args, "O:get_blueprint_hierarchy_from_class", &py_class))
1128+
{
1129+
return NULL;
1130+
}
1131+
1132+
UClass* u_class = ue_py_check_type<UClass>(py_class);
1133+
if (!u_class)
1134+
{
1135+
return PyErr_Format(PyExc_Exception, "argument is not a UClass");
1136+
}
1137+
1138+
1139+
TArray<UBlueprint*> outBPs;
1140+
UBlueprint::GetBlueprintHierarchyFromClass(u_class, outBPs);
1141+
1142+
PyObject *py_bpClasses = PyList_New(0);
1143+
1144+
for (UBlueprint* bpClass : outBPs) {
1145+
ue_PyUObject *item = ue_get_python_wrapper(bpClass);
1146+
if (item)
1147+
PyList_Append(py_bpClasses, (PyObject *)item);
1148+
}
1149+
return py_bpClasses;
1150+
}
11231151

11241152
PyObject *py_unreal_engine_reload_blueprint(PyObject * self, PyObject * args)
11251153
{
@@ -1602,6 +1630,35 @@ PyObject *py_unreal_engine_blueprint_add_ubergraph_page(PyObject * self, PyObjec
16021630
return ret;
16031631
}
16041632

1633+
PyObject *py_unreal_engine_blueprint_get_all_graphs(PyObject * self, PyObject * args)
1634+
{
1635+
PyObject *py_blueprint;
1636+
1637+
if (!PyArg_ParseTuple(args, "O:blueprint_get_all_graphs", &py_blueprint))
1638+
{
1639+
return nullptr;
1640+
}
1641+
1642+
UBlueprint *bp = ue_py_check_type<UBlueprint>(py_blueprint);
1643+
if (!bp)
1644+
return PyErr_Format(PyExc_Exception, "uobject is not a UBlueprint");
1645+
1646+
PyObject *py_graphs = PyList_New(0);
1647+
1648+
TArray<UEdGraph*> graphs;
1649+
1650+
bp->GetAllGraphs(graphs);
1651+
1652+
for (UEdGraph *graph : graphs)
1653+
{
1654+
ue_PyUObject *item = ue_get_python_wrapper(graph);
1655+
if (item)
1656+
PyList_Append(py_graphs, (PyObject *)item);
1657+
}
1658+
1659+
return py_graphs;
1660+
}
1661+
16051662
PyObject *py_unreal_engine_create_new_graph(PyObject * self, PyObject * args)
16061663
{
16071664

@@ -1665,35 +1722,6 @@ PyObject *py_unreal_engine_create_new_graph(PyObject * self, PyObject * args)
16651722
Py_RETURN_UOBJECT(graph);
16661723
}
16671724

1668-
PyObject *py_unreal_engine_editor_blueprint_graphs(PyObject * self, PyObject * args)
1669-
{
1670-
PyObject *py_blueprint;
1671-
1672-
if (!PyArg_ParseTuple(args, "O:blueprint_graphs", &py_blueprint))
1673-
{
1674-
return nullptr;
1675-
}
1676-
1677-
UBlueprint *bp = ue_py_check_type<UBlueprint>(py_blueprint);
1678-
if (!bp)
1679-
return PyErr_Format(PyExc_Exception, "uobject is not a UBlueprint");
1680-
1681-
PyObject *py_graphs = PyList_New(0);
1682-
1683-
TArray<UEdGraph*> graphs;
1684-
1685-
bp->GetAllGraphs(graphs);
1686-
1687-
for (UEdGraph *graph : graphs)
1688-
{
1689-
ue_PyUObject *item = ue_get_python_wrapper(graph);
1690-
if (item)
1691-
PyList_Append(py_graphs, (PyObject *)item);
1692-
}
1693-
1694-
return py_graphs;
1695-
}
1696-
16971725
PyObject *py_unreal_engine_editor_on_asset_post_import(PyObject * self, PyObject * args)
16981726
{
16991727
PyObject *py_callable;
@@ -2237,6 +2265,27 @@ PyObject *py_unreal_engine_register_settings(PyObject * self, PyObject * args)
22372265
Py_RETURN_NONE;
22382266
}
22392267

2268+
PyObject * py_unreal_engine_show_viewer(PyObject * self, PyObject * args)
2269+
{
2270+
char *container_name;
2271+
char *category_name;
2272+
char *section_name;
2273+
2274+
if (!PyArg_ParseTuple(args, "sss:register_settings", &container_name, &category_name, &section_name))
2275+
return nullptr;
2276+
2277+
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
2278+
{
2279+
SettingsModule->ShowViewer(container_name, category_name, section_name);
2280+
}
2281+
else
2282+
{
2283+
return PyErr_Format(PyExc_Exception, "unable to find the Settings Module");
2284+
}
2285+
2286+
Py_RETURN_NONE;
2287+
}
2288+
22402289
PyObject *py_unreal_engine_unregister_settings(PyObject * self, PyObject * args)
22412290
{
22422291
char *container_name;

‎Source/UnrealEnginePython/Private/UEPyEditor.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ PyObject *py_unreal_engine_get_long_package_path(PyObject *, PyObject *);
4040
PyObject *py_unreal_engine_create_blueprint(PyObject *, PyObject *);
4141
PyObject *py_unreal_engine_compile_blueprint(PyObject *, PyObject *);
4242
PyObject *py_unreal_engine_message_dialog_open(PyObject *, PyObject *);
43+
PyObject *py_unreal_engine_get_blueprint_hierarchy_from_class(PyObject *, PyObject *);
4344
PyObject *py_unreal_engine_reload_blueprint(PyObject *, PyObject *);
4445
PyObject *py_unreal_engine_replace_blueprint(PyObject *, PyObject *);
4546
PyObject *py_unreal_engine_create_blueprint_from_actor(PyObject *, PyObject *);
@@ -75,6 +76,7 @@ PyObject *py_unreal_engine_editor_take_high_res_screen_shots(PyObject *, PyObjec
7576

7677
PyObject *py_unreal_engine_blueprint_add_function(PyObject *, PyObject *);
7778
PyObject *py_unreal_engine_blueprint_add_ubergraph_page(PyObject *, PyObject *);
79+
PyObject *py_unreal_engine_blueprint_get_all_graphs(PyObject *, PyObject *);
7880

7981
PyObject *py_unreal_engine_create_new_graph(PyObject *, PyObject *);
8082

@@ -112,5 +114,6 @@ PyObject *py_unreal_engine_heightmap_import(PyObject *, PyObject *);
112114
PyObject *py_unreal_engine_play_preview_sound(PyObject *, PyObject *);
113115

114116
PyObject *py_unreal_engine_register_settings(PyObject *, PyObject *);
117+
PyObject *py_unreal_engine_show_viewer(PyObject *, PyObject *);
115118
PyObject *py_unreal_engine_unregister_settings(PyObject *, PyObject *);
116119
#endif

0 commit comments

Comments
 (0)