You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-07 12:30:27 +00:00
Refactor node processing in visual shader member dialog
This commit is contained in:
@@ -20,8 +20,8 @@
|
|||||||
<return type="String">
|
<return type="String">
|
||||||
</return>
|
</return>
|
||||||
<description>
|
<description>
|
||||||
Override this method to define the category of the associated custom node in the Visual Shader Editor's members dialog.
|
Override this method to define the path to the associated custom node in the Visual Shader Editor's members dialog. The path may looks like [code]"MyGame/MyFunctions/Noise"[/code].
|
||||||
Defining this method is [b]optional[/b]. If not overridden, the node will be filed under the "Custom" category.
|
Defining this method is [b]optional[/b]. If not overridden, the node will be filed under the "Addons" category.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_get_code" qualifiers="virtual">
|
<method name="_get_code" qualifiers="virtual">
|
||||||
@@ -135,14 +135,6 @@
|
|||||||
Defining this method is [b]optional[/b]. If not overridden, no return icon is shown.
|
Defining this method is [b]optional[/b]. If not overridden, no return icon is shown.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_get_subcategory" qualifiers="virtual">
|
|
||||||
<return type="String">
|
|
||||||
</return>
|
|
||||||
<description>
|
|
||||||
Override this method to define the subcategory of the associated custom node in the Visual Shader Editor's members dialog.
|
|
||||||
Defining this method is [b]optional[/b]. If not overridden, the node will be filed under the root of the main category (see [method _get_category]).
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="_is_highend" qualifiers="virtual">
|
<method name="_is_highend" qualifiers="virtual">
|
||||||
<return type="bool">
|
<return type="bool">
|
||||||
</return>
|
</return>
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ void VisualShaderEditor::clear_custom_types() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_subcategory, bool p_highend) {
|
void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, bool p_highend) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!p_name.is_valid_identifier());
|
ERR_FAIL_COND(!p_name.is_valid_identifier());
|
||||||
ERR_FAIL_COND(!p_script.is_valid());
|
ERR_FAIL_COND(!p_script.is_valid());
|
||||||
@@ -134,15 +134,15 @@ void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script>
|
|||||||
ao.return_type = p_return_icon_type;
|
ao.return_type = p_return_icon_type;
|
||||||
ao.description = p_description;
|
ao.description = p_description;
|
||||||
ao.category = p_category;
|
ao.category = p_category;
|
||||||
ao.sub_category = p_subcategory;
|
|
||||||
ao.highend = p_highend;
|
ao.highend = p_highend;
|
||||||
ao.is_custom = true;
|
ao.is_custom = true;
|
||||||
|
|
||||||
bool begin = false;
|
bool begin = false;
|
||||||
|
String root = p_category.split("/")[0];
|
||||||
|
|
||||||
for (int i = 0; i < add_options.size(); i++) {
|
for (int i = 0; i < add_options.size(); i++) {
|
||||||
if (add_options[i].is_custom) {
|
if (add_options[i].is_custom) {
|
||||||
if (add_options[i].category == p_category) {
|
if (add_options[i].category == root) {
|
||||||
if (!begin) {
|
if (!begin) {
|
||||||
begin = true;
|
begin = true;
|
||||||
}
|
}
|
||||||
@@ -239,9 +239,6 @@ void VisualShaderEditor::update_custom_nodes() {
|
|||||||
if (ref->has_method("_get_category")) {
|
if (ref->has_method("_get_category")) {
|
||||||
category = (String)ref->call("_get_category");
|
category = (String)ref->call("_get_category");
|
||||||
}
|
}
|
||||||
if (category == "") {
|
|
||||||
category = "Custom";
|
|
||||||
}
|
|
||||||
|
|
||||||
String subcategory = "";
|
String subcategory = "";
|
||||||
if (ref->has_method("_get_subcategory")) {
|
if (ref->has_method("_get_subcategory")) {
|
||||||
@@ -258,18 +255,19 @@ void VisualShaderEditor::update_custom_nodes() {
|
|||||||
dict["script"] = script;
|
dict["script"] = script;
|
||||||
dict["description"] = description;
|
dict["description"] = description;
|
||||||
dict["return_icon_type"] = return_icon_type;
|
dict["return_icon_type"] = return_icon_type;
|
||||||
|
|
||||||
|
category = category.rstrip("/");
|
||||||
|
category = category.lstrip("/");
|
||||||
|
category = "Addons/" + category;
|
||||||
|
if (subcategory != "") {
|
||||||
|
category += "/" + subcategory;
|
||||||
|
}
|
||||||
|
|
||||||
dict["category"] = category;
|
dict["category"] = category;
|
||||||
dict["subcategory"] = subcategory;
|
|
||||||
dict["highend"] = highend;
|
dict["highend"] = highend;
|
||||||
|
|
||||||
String key;
|
String key;
|
||||||
key = category;
|
key = category + "/" + name;
|
||||||
key += "/";
|
|
||||||
if (subcategory != "") {
|
|
||||||
key += subcategory;
|
|
||||||
key += "/";
|
|
||||||
}
|
|
||||||
key += name;
|
|
||||||
|
|
||||||
added[key] = dict;
|
added[key] = dict;
|
||||||
}
|
}
|
||||||
@@ -284,7 +282,7 @@ void VisualShaderEditor::update_custom_nodes() {
|
|||||||
|
|
||||||
const Dictionary &value = (Dictionary)added[key];
|
const Dictionary &value = (Dictionary)added[key];
|
||||||
|
|
||||||
add_custom_type(value["name"], value["script"], value["description"], value["return_icon_type"], value["category"], value["subcategory"], value["highend"]);
|
add_custom_type(value["name"], value["script"], value["description"], value["return_icon_type"], value["category"], value["highend"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_update_options_menu();
|
_update_options_menu();
|
||||||
@@ -299,22 +297,12 @@ void VisualShaderEditor::_update_options_menu() {
|
|||||||
node_desc->set_text("");
|
node_desc->set_text("");
|
||||||
members_dialog->get_ok()->set_disabled(true);
|
members_dialog->get_ok()->set_disabled(true);
|
||||||
|
|
||||||
String prev_category;
|
|
||||||
String prev_sub_category;
|
|
||||||
|
|
||||||
members->clear();
|
members->clear();
|
||||||
TreeItem *root = members->create_item();
|
TreeItem *root = members->create_item();
|
||||||
TreeItem *category = NULL;
|
|
||||||
TreeItem *sub_category = NULL;
|
|
||||||
|
|
||||||
String filter = node_filter->get_text().strip_edges();
|
String filter = node_filter->get_text().strip_edges();
|
||||||
bool use_filter = !filter.empty();
|
bool use_filter = !filter.empty();
|
||||||
|
|
||||||
Vector<String> categories;
|
|
||||||
Vector<String> sub_categories;
|
|
||||||
|
|
||||||
int item_count = 0;
|
|
||||||
int item_count2 = 0;
|
|
||||||
bool is_first_item = true;
|
bool is_first_item = true;
|
||||||
|
|
||||||
Color unsupported_color = get_color("error_color", "Editor");
|
Color unsupported_color = get_color("error_color", "Editor");
|
||||||
@@ -322,112 +310,93 @@ void VisualShaderEditor::_update_options_menu() {
|
|||||||
|
|
||||||
static bool low_driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES2";
|
static bool low_driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES2";
|
||||||
|
|
||||||
|
Map<String, TreeItem *> folders;
|
||||||
|
|
||||||
int current_func = -1;
|
int current_func = -1;
|
||||||
|
|
||||||
if (!visual_shader.is_null()) {
|
if (!visual_shader.is_null()) {
|
||||||
current_func = visual_shader->get_mode();
|
current_func = visual_shader->get_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < add_options.size() + 1; i++) {
|
Vector<AddOption> custom_options;
|
||||||
|
Vector<AddOption> embedded_options;
|
||||||
if (i == add_options.size()) {
|
|
||||||
if (sub_category != NULL && item_count2 == 0) {
|
|
||||||
memdelete(sub_category);
|
|
||||||
--item_count;
|
|
||||||
}
|
|
||||||
if (category != NULL && item_count == 0) {
|
|
||||||
memdelete(category);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (int i = 0; i < add_options.size(); i++) {
|
||||||
if (!use_filter || add_options[i].name.findn(filter) != -1) {
|
if (!use_filter || add_options[i].name.findn(filter) != -1) {
|
||||||
|
if ((add_options[i].func != current_func && add_options[i].func != -1) || !_is_available(add_options[i].mode)) {
|
||||||
if ((add_options[i].func != current_func && add_options[i].func != -1) || !_is_available(add_options[i].mode))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (prev_category != add_options[i].category) {
|
|
||||||
if (category != NULL && item_count == 0) {
|
|
||||||
memdelete(category);
|
|
||||||
}
|
|
||||||
|
|
||||||
item_count = 0;
|
|
||||||
prev_sub_category = "";
|
|
||||||
category = members->create_item(root);
|
|
||||||
category->set_text(0, add_options[i].category);
|
|
||||||
category->set_selectable(0, false);
|
|
||||||
if (!use_filter)
|
|
||||||
category->set_collapsed(true);
|
|
||||||
}
|
}
|
||||||
|
const_cast<AddOption &>(add_options[i]).temp_idx = i; // save valid id
|
||||||
if (add_options[i].sub_category != "") {
|
if (add_options[i].is_custom) {
|
||||||
if (prev_sub_category != add_options[i].sub_category) {
|
custom_options.push_back(add_options[i]);
|
||||||
if (category != NULL) {
|
|
||||||
if (sub_category != NULL && item_count2 == 0) {
|
|
||||||
memdelete(sub_category);
|
|
||||||
--item_count;
|
|
||||||
}
|
|
||||||
++item_count;
|
|
||||||
item_count2 = 0;
|
|
||||||
sub_category = members->create_item(category);
|
|
||||||
sub_category->set_text(0, add_options[i].sub_category);
|
|
||||||
sub_category->set_selectable(0, false);
|
|
||||||
if (!use_filter)
|
|
||||||
sub_category->set_collapsed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sub_category = NULL;
|
embedded_options.push_back(add_options[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *p_category = NULL;
|
|
||||||
|
|
||||||
if (sub_category != NULL) {
|
|
||||||
p_category = sub_category;
|
|
||||||
++item_count2;
|
|
||||||
} else if (category != NULL) {
|
|
||||||
p_category = category;
|
|
||||||
++item_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_category != NULL) {
|
|
||||||
TreeItem *item = members->create_item(p_category);
|
|
||||||
if (add_options[i].highend && low_driver)
|
|
||||||
item->set_custom_color(0, unsupported_color);
|
|
||||||
else if (add_options[i].highend)
|
|
||||||
item->set_custom_color(0, supported_color);
|
|
||||||
item->set_text(0, add_options[i].name);
|
|
||||||
if (is_first_item && use_filter) {
|
|
||||||
item->select(0);
|
|
||||||
node_desc->set_text(_get_description(i));
|
|
||||||
is_first_item = false;
|
|
||||||
}
|
|
||||||
switch (add_options[i].return_type) {
|
|
||||||
case VisualShaderNode::PORT_TYPE_SCALAR:
|
|
||||||
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"));
|
|
||||||
break;
|
|
||||||
case VisualShaderNode::PORT_TYPE_VECTOR:
|
|
||||||
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"));
|
|
||||||
break;
|
|
||||||
case VisualShaderNode::PORT_TYPE_BOOLEAN:
|
|
||||||
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"));
|
|
||||||
break;
|
|
||||||
case VisualShaderNode::PORT_TYPE_TRANSFORM:
|
|
||||||
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
|
|
||||||
break;
|
|
||||||
case VisualShaderNode::PORT_TYPE_SAMPLER:
|
|
||||||
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("ImageTexture", "EditorIcons"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
item->set_meta("id", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_sub_category = add_options[i].sub_category;
|
|
||||||
prev_category = add_options[i].category;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Vector<AddOption> options;
|
||||||
|
SortArray<AddOption, _OptionComparator> sorter;
|
||||||
|
sorter.sort(custom_options.ptrw(), custom_options.size());
|
||||||
|
|
||||||
|
options.append_array(custom_options);
|
||||||
|
options.append_array(embedded_options);
|
||||||
|
|
||||||
|
for (int i = 0; i < options.size(); i++) {
|
||||||
|
String path = options[i].category;
|
||||||
|
Vector<String> subfolders = path.split("/");
|
||||||
|
TreeItem *category = NULL;
|
||||||
|
|
||||||
|
if (!folders.has(path)) {
|
||||||
|
category = root;
|
||||||
|
String path_temp = "";
|
||||||
|
for (int j = 0; j < subfolders.size(); j++) {
|
||||||
|
path_temp += subfolders[j];
|
||||||
|
if (!folders.has(path_temp)) {
|
||||||
|
category = members->create_item(category);
|
||||||
|
category->set_selectable(0, false);
|
||||||
|
category->set_collapsed(!use_filter);
|
||||||
|
category->set_text(0, subfolders[j]);
|
||||||
|
folders.insert(path_temp, category);
|
||||||
|
} else {
|
||||||
|
category = folders[path_temp];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
category = folders[path];
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeItem *item = members->create_item(category);
|
||||||
|
if (options[i].highend && low_driver)
|
||||||
|
item->set_custom_color(0, unsupported_color);
|
||||||
|
else if (options[i].highend)
|
||||||
|
item->set_custom_color(0, supported_color);
|
||||||
|
item->set_text(0, options[i].name);
|
||||||
|
if (is_first_item && use_filter) {
|
||||||
|
item->select(0);
|
||||||
|
node_desc->set_text(options[i].description);
|
||||||
|
is_first_item = false;
|
||||||
|
}
|
||||||
|
switch (options[i].return_type) {
|
||||||
|
case VisualShaderNode::PORT_TYPE_SCALAR:
|
||||||
|
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"));
|
||||||
|
break;
|
||||||
|
case VisualShaderNode::PORT_TYPE_VECTOR:
|
||||||
|
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"));
|
||||||
|
break;
|
||||||
|
case VisualShaderNode::PORT_TYPE_BOOLEAN:
|
||||||
|
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"));
|
||||||
|
break;
|
||||||
|
case VisualShaderNode::PORT_TYPE_TRANSFORM:
|
||||||
|
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
|
||||||
|
break;
|
||||||
|
case VisualShaderNode::PORT_TYPE_SAMPLER:
|
||||||
|
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("ImageTexture", "EditorIcons"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
item->set_meta("id", options[i].temp_idx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Size2 VisualShaderEditor::get_minimum_size() const {
|
Size2 VisualShaderEditor::get_minimum_size() const {
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ class VisualShaderEditor : public VBoxContainer {
|
|||||||
struct AddOption {
|
struct AddOption {
|
||||||
String name;
|
String name;
|
||||||
String category;
|
String category;
|
||||||
String sub_category;
|
|
||||||
String type;
|
String type;
|
||||||
String description;
|
String description;
|
||||||
int sub_func;
|
int sub_func;
|
||||||
@@ -116,12 +115,12 @@ class VisualShaderEditor : public VBoxContainer {
|
|||||||
float value;
|
float value;
|
||||||
bool highend;
|
bool highend;
|
||||||
bool is_custom;
|
bool is_custom;
|
||||||
|
int temp_idx;
|
||||||
|
|
||||||
AddOption(const String &p_name = String(), const String &p_category = String(), const String &p_sub_category = String(), const String &p_type = String(), const String &p_description = String(), int p_sub_func = -1, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
|
AddOption(const String &p_name = String(), const String &p_category = String(), const String &p_sub_category = String(), const String &p_type = String(), const String &p_description = String(), int p_sub_func = -1, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
|
||||||
name = p_name;
|
name = p_name;
|
||||||
type = p_type;
|
type = p_type;
|
||||||
category = p_category;
|
category = p_category + "/" + p_sub_category;
|
||||||
sub_category = p_sub_category;
|
|
||||||
description = p_description;
|
description = p_description;
|
||||||
sub_func = p_sub_func;
|
sub_func = p_sub_func;
|
||||||
return_type = p_return_type;
|
return_type = p_return_type;
|
||||||
@@ -135,8 +134,7 @@ class VisualShaderEditor : public VBoxContainer {
|
|||||||
AddOption(const String &p_name, const String &p_category, const String &p_sub_category, const String &p_type, const String &p_description, const String &p_sub_func, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
|
AddOption(const String &p_name, const String &p_category, const String &p_sub_category, const String &p_type, const String &p_description, const String &p_sub_func, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
|
||||||
name = p_name;
|
name = p_name;
|
||||||
type = p_type;
|
type = p_type;
|
||||||
category = p_category;
|
category = p_category + "/" + p_sub_category;
|
||||||
sub_category = p_sub_category;
|
|
||||||
description = p_description;
|
description = p_description;
|
||||||
sub_func = 0;
|
sub_func = 0;
|
||||||
sub_func_str = p_sub_func;
|
sub_func_str = p_sub_func;
|
||||||
@@ -148,6 +146,12 @@ class VisualShaderEditor : public VBoxContainer {
|
|||||||
is_custom = false;
|
is_custom = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
struct _OptionComparator {
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool operator()(const AddOption &a, const AddOption &b) const {
|
||||||
|
return a.category.count("/") > b.category.count("/") || (a.category + "/" + a.name).naturalnocasecmp_to(b.category + "/" + b.name) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Vector<AddOption> add_options;
|
Vector<AddOption> add_options;
|
||||||
int texture_node_option_idx;
|
int texture_node_option_idx;
|
||||||
@@ -265,7 +269,7 @@ public:
|
|||||||
static VisualShaderEditor *get_singleton() { return singleton; }
|
static VisualShaderEditor *get_singleton() { return singleton; }
|
||||||
|
|
||||||
void clear_custom_types();
|
void clear_custom_types();
|
||||||
void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_subcategory, bool p_highend);
|
void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, bool p_highend);
|
||||||
|
|
||||||
virtual Size2 get_minimum_size() const;
|
virtual Size2 get_minimum_size() const;
|
||||||
void edit(VisualShader *p_visual_shader);
|
void edit(VisualShader *p_visual_shader);
|
||||||
|
|||||||
@@ -266,7 +266,6 @@ void VisualShaderNodeCustom::_bind_methods() {
|
|||||||
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
|
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
|
||||||
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description"));
|
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description"));
|
||||||
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
|
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
|
||||||
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_subcategory"));
|
|
||||||
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type"));
|
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type"));
|
||||||
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count"));
|
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count"));
|
||||||
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port")));
|
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port")));
|
||||||
|
|||||||
Reference in New Issue
Block a user