Skip to content

Commit

Permalink
Merge branch 'pr/16'
Browse files Browse the repository at this point in the history
  • Loading branch information
getnamo committed Sep 12, 2019
2 parents d6cf725 + 038192d commit 9b20b3d
Show file tree
Hide file tree
Showing 23 changed files with 624 additions and 358 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ Binaries/

#don't update this file again
Content/Scripts/upyconfig.json
Intermediate/

python35/
python27/
*.un~
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Once the plugin is installed and enabled, you get access to the 'PythonConsole'

All of the exposed engine features are under the 'unreal_engine' virtual module (it is completely coded in c into the plugin, so do not expect to run 'import unreal_engine' from a standard python shell)

The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17, 4.18, 4.19, 4.20 and 4.21
The minimal supported Unreal Engine version is 4.12, while the latest is 4.23

We support official python.org releases as well as IntelPython and Anaconda distributions.

Expand Down
4 changes: 4 additions & 0 deletions Source/PythonAutomation/Public/PythonAutomationModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
#pragma once

#include "CoreMinimal.h"
#if ENGINE_MAJOR_VERSION==4 && ENGINE_MINOR_VERSION>=22
#include "Modules/ModuleInterface.h"
#else
#include "ModuleInterface.h"
#endif

class FPythonAutomationModule : public IModuleInterface
{
Expand Down
121 changes: 121 additions & 0 deletions Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,127 @@ PyObject *py_ue_graph_add_node(ue_PyUObject * self, PyObject * args)
Py_RETURN_UOBJECT(node);
}

PyObject *py_ue_graph_remove_node(ue_PyUObject * self, PyObject * args)
{

ue_py_check(self);

PyObject *py_node_class;
int x = 0;
int y = 0;

char *metadata = nullptr;
PyObject *py_data = nullptr;

if (!PyArg_ParseTuple(args, "O|iisO:graph_remove_node", &py_node_class, &x, &y, &metadata, &py_data))
{
return nullptr;
}

UEdGraph *graph = ue_py_check_type<UEdGraph>(self);
if (!graph)
return PyErr_Format(PyExc_Exception, "uobject is not a UEdGraph");

UObject *u_obj = ue_py_check_type<UObject>(py_node_class);
if (!u_obj)
return PyErr_Format(PyExc_Exception, "argument is not a UObject");

UEdGraphNode *node = nullptr;

if (UClass *u_class = Cast<UClass>(u_obj))
{
if (!u_class->IsChildOf<UEdGraphNode>())
{
return PyErr_Format(PyExc_Exception, "argument is not a child of UEdGraphNode");
}
node = NewObject<UEdGraphNode>(graph, u_class);
node->PostLoad();
}
else
{
node = Cast<UEdGraphNode>(u_obj);
if (node)
{
if (node->GetOuter() != graph)

node->Rename(*node->GetName(), graph);
}
}

if (!node)
return PyErr_Format(PyExc_Exception, "argument is not a supported type");

graph->RemoveNode(node);

if (UBlueprint *bp = Cast<UBlueprint>(node->GetGraph()->GetOuter()))
{
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp);
}

Py_RETURN_NONE;
}

PyObject *py_ue_graph_reconstruct_node(ue_PyUObject * self, PyObject * args)
{

ue_py_check(self);

PyObject *py_node_class;
int x = 0;
int y = 0;

char *metadata = nullptr;
PyObject *py_data = nullptr;

if (!PyArg_ParseTuple(args, "O|iisO:graph_reconstruct_node", &py_node_class, &x, &y, &metadata, &py_data))
{
return nullptr;
}

UEdGraph *graph = ue_py_check_type<UEdGraph>(self);
if (!graph)
return PyErr_Format(PyExc_Exception, "uobject is not a UEdGraph");

UObject *u_obj = ue_py_check_type<UObject>(py_node_class);
if (!u_obj)
return PyErr_Format(PyExc_Exception, "argument is not a UObject");

UEdGraphNode *node = nullptr;

if (UClass *u_class = Cast<UClass>(u_obj))
{
if (!u_class->IsChildOf<UEdGraphNode>())
{
return PyErr_Format(PyExc_Exception, "argument is not a child of UEdGraphNode");
}
node = NewObject<UEdGraphNode>(graph, u_class);
node->PostLoad();
}
else
{
node = Cast<UEdGraphNode>(u_obj);
if (node)
{
if (node->GetOuter() != graph)

node->Rename(*node->GetName(), graph);
}
}

if (!node)
return PyErr_Format(PyExc_Exception, "argument is not a supported type");

//graph->RemoveNode(node);
node->ReconstructNode();

if (UBlueprint *bp = Cast<UBlueprint>(node->GetGraph()->GetOuter()))
{
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp);
}

Py_RETURN_NONE;
}

PyObject *py_ue_graph_add_node_dynamic_cast(ue_PyUObject * self, PyObject * args)
{

Expand Down
3 changes: 3 additions & 0 deletions Source/UnrealEnginePython/Private/Blueprint/UEPyEdGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ PyObject *py_ue_graph_add_node(ue_PyUObject *, PyObject *);
PyObject *py_ue_graph_add_node_dynamic_cast(ue_PyUObject *, PyObject *);
PyObject *py_ue_graph_add_node_event(ue_PyUObject *, PyObject *);

PyObject *py_ue_graph_reconstruct_node(ue_PyUObject *, PyObject *);
PyObject *py_ue_graph_remove_node(ue_PyUObject *, PyObject *);

PyObject *py_ue_graph_get_good_place_for_new_node(ue_PyUObject *, PyObject *);

PyObject *py_ue_node_pins(ue_PyUObject *, PyObject *);
Expand Down
1 change: 0 additions & 1 deletion Source/UnrealEnginePython/Private/PythonHouseKeeper.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#pragma once

#include "PythonHouseKeeper.h"

Expand Down
76 changes: 42 additions & 34 deletions Source/UnrealEnginePython/Private/Slate/UEPyFMenuBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

#include "Wrappers/UEPyESlateEnums.h"

static PyObject *py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder* self, PyObject* args)
{
char *name;
char *text;
char* name;
char* text;
if (!PyArg_ParseTuple(args, "ss:begin_section", &name, &text))
return nullptr;

Expand All @@ -14,27 +14,31 @@ static PyObject *py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder *self, PyOb
Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_end_section(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_end_section(ue_PyFMenuBuilder* self, PyObject* args)
{
self->menu_builder.EndSection();

Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_make_widget(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_make_widget(ue_PyFMenuBuilder* self, PyObject* args)
{
ue_PySWidget *ret = (ue_PySWidget *)PyObject_New(ue_PySWidget, &ue_PySWidgetType);
ue_PySWidget* ret = (ue_PySWidget*)PyObject_New(ue_PySWidget, &ue_PySWidgetType);
new (&ret->Widget) TSharedRef<SWidget>(self->menu_builder.MakeWidget());
return (PyObject *)ret;
return (PyObject*)ret;
}

static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder* self, PyObject* args)
{
char *label;
char *tooltip;
PyObject *py_callable;
PyObject *py_obj = nullptr;
char* label;
char* tooltip;
PyObject* py_callable;
PyObject* py_obj = nullptr;
#if ENGINE_MINOR_VERSION >= 23
int ui_action_type = (int)EUserInterfaceActionType::Button;
#else
int ui_action_type = EUserInterfaceActionType::Button;
#endif
if (!PyArg_ParseTuple(args, "ssO|Oi:add_menu_entry", &label, &tooltip, &py_callable, &py_obj, &ui_action_type))
return nullptr;

Expand All @@ -58,17 +62,21 @@ static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyO
}

self->menu_builder.AddMenuEntry(FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), FSlateIcon(), FUIAction(handler), NAME_None,
#if ENGINE_MINOR_VERSION >= 23
(EUserInterfaceActionType)ui_action_type);
#else
(EUserInterfaceActionType::Type)ui_action_type);
#endif

Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder* self, PyObject* args)
{
char *label;
char *tooltip;
PyObject *py_callable;
PyObject *py_bool = nullptr;
char* label;
char* tooltip;
PyObject* py_callable;
PyObject* py_bool = nullptr;
if (!PyArg_ParseTuple(args, "ssO|O:add_sub_menu", &label, &tooltip, &py_callable, &py_bool))
return nullptr;

Expand All @@ -77,7 +85,7 @@ static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObj
return PyErr_Format(PyExc_Exception, "argument is not callable");
}


TSharedRef<FPythonSlateDelegate> py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewStaticSlateDelegate(py_callable);

FNewMenuDelegate menu_delegate;
Expand All @@ -89,9 +97,9 @@ static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObj
Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder* self, PyObject* args)
{
char *name = nullptr;
char* name = nullptr;

if (!PyArg_ParseTuple(args, "|s:add_menu_separator", &name))
return nullptr;
Expand All @@ -107,9 +115,9 @@ static PyObject *py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder *self,
}

#if WITH_EDITOR
static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder* self, PyObject* args)
{
PyObject *py_assets;
PyObject* py_assets;

if (!PyArg_ParseTuple(args, "O:add_asset_actions", &py_assets))
return nullptr;
Expand All @@ -120,10 +128,10 @@ static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self,
return PyErr_Format(PyExc_Exception, "argument is not iterable");
}

TArray<UObject *> u_objects;
while (PyObject *item = PyIter_Next(py_assets))
TArray<UObject*> u_objects;
while (PyObject * item = PyIter_Next(py_assets))
{
UObject *u_object = ue_py_check_type<UObject>(item);
UObject* u_object = ue_py_check_type<UObject>(item);
if (u_object)
{
u_objects.Add(u_object);
Expand All @@ -142,7 +150,7 @@ static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self,
}
#endif

static PyObject *py_ue_fmenu_builder_add_search_widget(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_search_widget(ue_PyFMenuBuilder* self, PyObject* args)
{
self->menu_builder.AddSearchWidget();

Expand All @@ -164,13 +172,13 @@ static PyMethodDef ue_PyFMenuBuilder_methods[] = {
};


static PyObject *ue_PyFMenuBuilder_str(ue_PyFMenuBuilder *self)
static PyObject* ue_PyFMenuBuilder_str(ue_PyFMenuBuilder* self)
{
return PyUnicode_FromFormat("<unreal_engine.FMenuBuilder '%p'}>",
&self->menu_builder);
}

static void ue_py_fmenu_builder_dealloc(ue_PyFMenuBuilder *self)
static void ue_py_fmenu_builder_dealloc(ue_PyFMenuBuilder* self)
{
#if PY_MAJOR_VERSION < 3
self->ob_type->tp_free((PyObject*)self);
Expand Down Expand Up @@ -210,14 +218,14 @@ static PyTypeObject ue_PyFMenuBuilderType = {
ue_PyFMenuBuilder_methods, /* tp_methods */
};

static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder *self, PyObject *args, PyObject *kwargs)
static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder* self, PyObject* args, PyObject* kwargs)
{
new(&self->menu_builder) FMenuBuilder(true, nullptr);
return 0;
}


void ue_python_init_fmenu_builder(PyObject *ue_module)
void ue_python_init_fmenu_builder(PyObject* ue_module)
{
ue_PyFMenuBuilderType.tp_new = PyType_GenericNew;

Expand All @@ -227,12 +235,12 @@ void ue_python_init_fmenu_builder(PyObject *ue_module)
return;

Py_INCREF(&ue_PyFMenuBuilderType);
PyModule_AddObject(ue_module, "FMenuBuilder", (PyObject *)&ue_PyFMenuBuilderType);
PyModule_AddObject(ue_module, "FMenuBuilder", (PyObject*)& ue_PyFMenuBuilderType);
}

PyObject *py_ue_new_fmenu_builder(FMenuBuilder menu_builder)
PyObject* py_ue_new_fmenu_builder(FMenuBuilder menu_builder)
{
ue_PyFMenuBuilder *ret = (ue_PyFMenuBuilder *)PyObject_New(ue_PyFMenuBuilder, &ue_PyFMenuBuilderType);
ue_PyFMenuBuilder* ret = (ue_PyFMenuBuilder*)PyObject_New(ue_PyFMenuBuilder, &ue_PyFMenuBuilderType);
new(&ret->menu_builder) FMenuBuilder(menu_builder);
return (PyObject *)ret;
return (PyObject*)ret;
}
4 changes: 4 additions & 0 deletions Source/UnrealEnginePython/Private/Slate/UEPySTextBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ static int ue_py_stext_block_init(ue_PySTextBlock *self, PyObject *args, PyObjec
ue_py_slate_farguments_float("line_height_percentage", LineHeightPercentage);
ue_py_slate_farguments_struct("margin", Margin, FMargin);
ue_py_slate_farguments_float("min_desired_width", MinDesiredWidth);
#if ENGINE_MINOR_VERSION >= 23
ue_py_slate_farguments_event("on_double_clicked", OnDoubleClicked, FPointerEventHandler, OnMouseEvent);
#else
ue_py_slate_farguments_event("on_double_clicked", OnDoubleClicked, FOnClicked, OnClicked);
#endif
ue_py_slate_farguments_flinear_color("shadow_color_and_opacity", ShadowColorAndOpacity);
ue_py_slate_farguments_fvector2d("shadow_offset", ShadowOffset);
ue_py_slate_farguments_text("text", Text);
Expand Down
5 changes: 4 additions & 1 deletion Source/UnrealEnginePython/Private/Slate/UEPySlate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1020,8 +1020,11 @@ class FPythonSlateCommands : public TCommands<FPythonSlateCommands>
virtual void RegisterCommands() override
{
commands = MakeShareable(new FUICommandList);

#if ENGINE_MINOR_VERSION >= 23
MakeUICommand_InternalUseOnly(this, command, nullptr, *name, *name, TCHAR_TO_UTF8(*name), *name, *name, EUserInterfaceActionType::Button, FInputGesture());
#else
UI_COMMAND_Function(this, command, nullptr, *name, *name, TCHAR_TO_UTF8(*name), *name, *name, EUserInterfaceActionType::Button, FInputGesture());
#endif
commands->MapAction(command, FExecuteAction::CreateRaw(this, &FPythonSlateCommands::Callback), FCanExecuteAction());
}

Expand Down
Loading

0 comments on commit 9b20b3d

Please sign in to comment.