Skip to content

Commit

Permalink
GH-640 Add dragging function creates callable
Browse files Browse the repository at this point in the history
  • Loading branch information
Naros committed Aug 10, 2024
1 parent 0124555 commit 5083638
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 4 deletions.
9 changes: 9 additions & 0 deletions src/common/dictionary_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,13 @@ namespace DictionaryUtils

return properties;
}

Array from_properties(const Vector<PropertyInfo>& p_properties)
{
TypedArray<Dictionary> result;
for (const PropertyInfo& property : p_properties)
result.push_back(from_property(property));

return result;
}
}
6 changes: 6 additions & 0 deletions src/common/dictionary_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <godot_cpp/core/method_bind.hpp>
#include <godot_cpp/core/property_info.hpp>
#include <godot_cpp/templates/vector.hpp>

using namespace godot;

Expand Down Expand Up @@ -71,6 +72,11 @@ namespace DictionaryUtils
/// @param p_sorted whether to sort the properties by name
/// @return the list of property info objects
List<PropertyInfo> to_properties(const TypedArray<Dictionary>& p_array, bool p_sorted = false);

/// Converts a vector of property infos to an array of dictionary entries
/// @param p_properties the properties
/// @return an array of dictionaries
Array from_properties(const Vector<PropertyInfo>& p_properties);
}

#endif // ORCHESTRATOR_DICTIONARY_UTILS_H
83 changes: 80 additions & 3 deletions src/editor/graph/graph_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,9 +664,18 @@ void OrchestratorGraphEdit::_drop_data(const Vector2& p_position, const Variant&
{
if (data.has("functions"))
{
OScriptNodeInitContext context;
context.method = DictionaryUtils::to_method(data["functions"]);
spawn_node<OScriptNodeCallScriptFunction>(context, _saved_mouse_position);
MethodInfo method = DictionaryUtils::to_method(data["functions"]);

// Create context-menu to specify variable get or set choice
_context_menu->clear();
_context_menu->add_separator("Function " + method.name);
_context_menu->add_item("Add Call Function", CM_FUNCTION_CALL);
_context_menu->add_item("Add Callable", CM_FUNCTION_CALLABLE);
_context_menu->set_item_metadata(_context_menu->get_item_index(CM_FUNCTION_CALL), data["functions"]);
_context_menu->set_item_metadata(_context_menu->get_item_index(CM_FUNCTION_CALLABLE), data["functions"]);
_context_menu->reset_size();
_context_menu->set_position(get_screen_position() + p_position);
_context_menu->popup();
}
}
else if (type == "variable")
Expand Down Expand Up @@ -1239,6 +1248,9 @@ void OrchestratorGraphEdit::_show_action_menu(const Vector2& p_position, const O
void OrchestratorGraphEdit::_update_saved_mouse_position(const Vector2& p_position)
{
_saved_mouse_position = (p_position + get_scroll_offset()) / get_zoom();

if (is_snapping_enabled())
_saved_mouse_position = _saved_mouse_position.snappedf(get_snapping_distance());
}

void OrchestratorGraphEdit::_show_drag_hint(const godot::String& p_message) const
Expand All @@ -1257,6 +1269,56 @@ void OrchestratorGraphEdit::_hide_drag_hint()
_drag_hint->hide();
}

void OrchestratorGraphEdit::_create_script_function_callable(const StringName& p_function_name)
{
BuiltInType callable_type = ExtensionDB::get_builtin_type(Variant::CALLABLE);

int ctor_index = 0;
bool found = false;
for (; ctor_index < callable_type.constructors.size(); ++ctor_index)
{
const ConstructorInfo& ctor = callable_type.constructors[ctor_index];
if (ctor.arguments.size() == 2
&& ctor.arguments[0].type == Variant::OBJECT
&& ctor.arguments[1].type == Variant::STRING_NAME)
{
found = true;
break;
}
}

if (!found)
return;

const Vector<PropertyInfo>& properties = callable_type.constructors[ctor_index].arguments;
const Array arguments = DictionaryUtils::from_properties(properties);

Dictionary spawn_data;
spawn_data["type"] = Variant::CALLABLE;
spawn_data["constructor_args"] = arguments;

OScriptNodeInitContext compose_context;
compose_context.user_data = spawn_data;

spawn_node<OScriptNodeComposeFrom>(
compose_context,
_saved_mouse_position,
callable_mp_lambda(this, [=](OScriptNodeComposeFrom* compose) {
compose->find_pin(1, PD_Input)->set_default_value(p_function_name);
compose->reconstruct_node();

const Vector2 self_position = _saved_mouse_position - Vector2(200, 0);

OScriptNodeInitContext self_context;
spawn_node<OScriptNodeSelf>(
self_context,
self_position,
callable_mp_lambda(this, [=](OScriptNodeSelf* self) {
self->find_pin(0, PD_Output)->link(compose->find_pin(0, PD_Input));
}));
}));
}

void OrchestratorGraphEdit::_on_connection_drag_started(const StringName& p_from, int p_from_port, bool p_output)
{
OrchestratorSettings* os = OrchestratorSettings::get_singleton();
Expand Down Expand Up @@ -1676,6 +1738,21 @@ void OrchestratorGraphEdit::_on_context_menu_selection(int p_id)
handler->execute(this, _saved_mouse_position);
break;
}
case CM_FUNCTION_CALL:
{
int index = _context_menu->get_item_index(p_id);
OScriptNodeInitContext context;
context.method = DictionaryUtils::to_method(_context_menu->get_item_metadata(index));
spawn_node<OScriptNodeCallScriptFunction>(context, _saved_mouse_position);
break;
}
case CM_FUNCTION_CALLABLE:
{
int index = _context_menu->get_item_index(p_id);
MethodInfo method = DictionaryUtils::to_method(_context_menu->get_item_metadata(index));
_create_script_function_callable(method.name);
break;
}
case CM_FILE_GET_PATH:
case CM_FILE_PRELOAD:
{
Expand Down
8 changes: 7 additions & 1 deletion src/editor/graph/graph_edit.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ class OrchestratorGraphEdit : public GraphEdit
CM_PROPERTY_GET,
CM_PROPERTY_SET,
CM_FILE_GET_PATH,
CM_FILE_PRELOAD
CM_FILE_PRELOAD,
CM_FUNCTION_CALL,
CM_FUNCTION_CALLABLE
};

/// Simple drag state for the graph
Expand Down Expand Up @@ -373,6 +375,10 @@ class OrchestratorGraphEdit : public GraphEdit
/// Hides the drag status hint
void _hide_drag_hint();

/// Creates a callable mapping for the script function
/// @param p_function_name the name of the function to call
void _create_script_function_callable(const StringName& p_function_name);

/// Connection drag started
/// @param p_from the source node
/// @param p_from_port source node port
Expand Down

0 comments on commit 5083638

Please sign in to comment.