summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/TextEdit.xml5
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp10
-rw-r--r--scene/gui/code_edit.cpp44
-rw-r--r--scene/gui/code_edit.h10
-rw-r--r--scene/gui/text_edit.cpp5
-rw-r--r--scene/resources/visual_shader.cpp78
-rw-r--r--scene/resources/visual_shader_nodes.cpp5
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp4
8 files changed, 143 insertions, 18 deletions
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index c31b7b953e..68d20e41d0 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -1014,6 +1014,11 @@
Emitted when the text changes.
</description>
</signal>
+ <signal name="text_set">
+ <description>
+ Emitted when [method clear] is called or [member text] is set.
+ </description>
+ </signal>
</signals>
<constants>
<constant name="MENU_CUT" value="0" enum="MenuItems">
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 37a04a1844..d6ac238414 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -592,6 +592,14 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
}
if (vsnode->is_use_prop_slots()) {
+ String error = vsnode->get_warning(visual_shader->get_mode(), p_type);
+ if (error != String()) {
+ Label *error_label = memnew(Label);
+ error_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_label->set_text(error);
+ node->add_child(error_label);
+ }
+
return;
}
custom_editor = nullptr;
@@ -2029,6 +2037,8 @@ void VisualShaderEditor::_uniform_line_edit_changed(const String &p_text, int p_
undo_redo->add_undo_method(node.ptr(), "set_uniform_name", node->get_uniform_name());
undo_redo->add_do_method(graph_plugin.ptr(), "set_uniform_name", type, p_node_id, validated_name);
undo_redo->add_undo_method(graph_plugin.ptr(), "set_uniform_name", type, p_node_id, node->get_uniform_name());
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node_deferred", type, p_node_id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node_deferred", type, p_node_id);
undo_redo->add_do_method(this, "_update_uniforms", true);
undo_redo->add_undo_method(this, "_update_uniforms", true);
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 87b950746c..503f9ffd4a 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -633,7 +633,7 @@ void CodeEdit::_backspace() {
int prev_line = cc ? cl : cl - 1;
int prev_column = cc ? (cc - 1) : (get_line(cl - 1).length());
- merge_gutters(cl, prev_line);
+ merge_gutters(prev_line, cl);
if (auto_brace_completion_enabled && cc > 0) {
int idx = _get_auto_brace_pair_open_at_pos(cl, cc);
@@ -1178,6 +1178,8 @@ void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2
// Breakpoints
void CodeEdit::set_line_as_breakpoint(int p_line, bool p_breakpointed) {
+ ERR_FAIL_INDEX(p_line, get_line_count());
+
int mask = get_line_gutter_metadata(p_line, main_gutter);
set_line_gutter_metadata(p_line, main_gutter, p_breakpointed ? mask | MAIN_GUTTER_BREAKPOINT : mask & ~MAIN_GUTTER_BREAKPOINT);
if (p_breakpointed) {
@@ -2884,6 +2886,21 @@ void CodeEdit::_lines_edited_from(int p_from_line, int p_to_line) {
return;
}
+ lines_edited_from = (lines_edited_from == -1) ? MIN(p_from_line, p_to_line) : MIN(lines_edited_from, MIN(p_from_line, p_to_line));
+ lines_edited_to = (lines_edited_to == -1) ? MAX(p_from_line, p_to_line) : MAX(lines_edited_from, MAX(p_from_line, p_to_line));
+}
+
+void CodeEdit::_text_set() {
+ lines_edited_from = 0;
+ lines_edited_to = 9999;
+ _text_changed();
+}
+
+void CodeEdit::_text_changed() {
+ if (lines_edited_from == -1) {
+ return;
+ }
+
int lc = get_line_count();
line_number_digits = 1;
while (lc /= 10) {
@@ -2891,23 +2908,28 @@ void CodeEdit::_lines_edited_from(int p_from_line, int p_to_line) {
}
set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', 0, font_size).width);
- int from_line = MIN(p_from_line, p_to_line);
- int line_count = (p_to_line - p_from_line);
+ lc = get_line_count();
+ int line_change_size = (lines_edited_to - lines_edited_from);
List<int> breakpoints;
breakpointed_lines.get_key_list(&breakpoints);
- for (const int line : breakpoints) {
- if (line <= from_line) {
+ for (const int &line : breakpoints) {
+ if (line < lines_edited_from || (line < lc && is_line_breakpointed(line))) {
continue;
}
- breakpointed_lines.erase(line);
+ breakpointed_lines.erase(line);
emit_signal(SNAME("breakpoint_toggled"), line);
- if (line_count > 0 || line >= p_from_line) {
- emit_signal(SNAME("breakpoint_toggled"), line + line_count);
- breakpointed_lines[line + line_count] = true;
+
+ int next_line = line + line_change_size;
+ if (next_line < lc && is_line_breakpointed(next_line)) {
+ emit_signal(SNAME("breakpoint_toggled"), next_line);
+ breakpointed_lines[next_line] = true;
continue;
}
}
+
+ lines_edited_from = -1;
+ lines_edited_to = -1;
}
CodeEdit::CodeEdit() {
@@ -2961,8 +2983,10 @@ CodeEdit::CodeEdit() {
gutter_idx++;
connect("lines_edited_from", callable_mp(this, &CodeEdit::_lines_edited_from));
- connect("gutter_clicked", callable_mp(this, &CodeEdit::_gutter_clicked));
+ connect("text_set", callable_mp(this, &CodeEdit::_text_set));
+ connect("text_changed", callable_mp(this, &CodeEdit::_text_changed));
+ connect("gutter_clicked", callable_mp(this, &CodeEdit::_gutter_clicked));
connect("gutter_added", callable_mp(this, &CodeEdit::_update_gutter_indexes));
connect("gutter_removed", callable_mp(this, &CodeEdit::_update_gutter_indexes));
_update_gutter_indexes();
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index 558c7adaea..76ac15f553 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -221,8 +221,6 @@ private:
void _filter_code_completion_candidates();
- void _lines_edited_from(int p_from_line, int p_to_line);
-
/* Line length guidelines */
TypedArray<int> line_length_guideline_columns;
Color line_length_guideline_color;
@@ -241,6 +239,14 @@ private:
int line_spacing = 1;
+ /* Callbacks */
+ int lines_edited_from = -1;
+ int lines_edited_to = -1;
+
+ void _lines_edited_from(int p_from_line, int p_to_line);
+ void _text_set();
+ void _text_changed();
+
protected:
void _gui_input(const Ref<InputEvent> &p_gui_input) override;
void _notification(int p_what);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 65f6cfcf17..443eb68bc5 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2449,6 +2449,7 @@ void TextEdit::clear() {
setting_text = true;
_clear();
setting_text = false;
+ emit_signal(SNAME("text_set"));
}
void TextEdit::_clear() {
@@ -2486,6 +2487,7 @@ void TextEdit::set_text(const String &p_text) {
update();
setting_text = false;
+ emit_signal(SNAME("text_set"));
}
String TextEdit::get_text() const {
@@ -4709,6 +4711,7 @@ void TextEdit::_bind_methods() {
/* Signals */
/* Core. */
+ ADD_SIGNAL(MethodInfo("text_set"));
ADD_SIGNAL(MethodInfo("text_changed"));
ADD_SIGNAL(MethodInfo("lines_edited_from", PropertyInfo(Variant::INT, "from_line"), PropertyInfo(Variant::INT, "to_line")));
@@ -4875,7 +4878,7 @@ void TextEdit::_backspace() {
int prev_line = cc ? cl : cl - 1;
int prev_column = cc ? (cc - 1) : (text[cl - 1].length());
- merge_gutters(cl, prev_line);
+ merge_gutters(prev_line, cl);
if (_is_line_hidden(cl)) {
_set_line_as_hidden(prev_line, true);
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index a6815da6f4..75dd7448e7 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -3081,10 +3081,84 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T
List<String> keyword_list;
ShaderLanguage::get_keyword_list(&keyword_list);
if (keyword_list.find(uniform_name)) {
- return TTR("Uniform name cannot be equal to a shader keyword. Choose another name.");
+ return TTR("Shader keywords cannot be used as uniform names.\nChoose another name.");
}
if (!is_qualifier_supported(qualifier)) {
- return "This uniform type does not support that qualifier.";
+ String qualifier_str;
+ switch (qualifier) {
+ case QUAL_NONE:
+ break;
+ case QUAL_GLOBAL:
+ qualifier_str = "global";
+ break;
+ case QUAL_INSTANCE:
+ qualifier_str = "instance";
+ break;
+ }
+ return vformat(TTR("This uniform type does not support the '%s' qualifier."), qualifier_str);
+ } else if (qualifier == Qualifier::QUAL_GLOBAL) {
+ RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(uniform_name);
+ if (gvt == RS::GLOBAL_VAR_TYPE_MAX) {
+ return vformat(TTR("Global uniform '%s' does not exist.\nCreate it in the Project Settings."), uniform_name);
+ }
+ bool incompatible_type = false;
+ switch (gvt) {
+ case RS::GLOBAL_VAR_TYPE_FLOAT: {
+ if (!Object::cast_to<VisualShaderNodeFloatUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_INT: {
+ if (!Object::cast_to<VisualShaderNodeIntUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_BOOL: {
+ if (!Object::cast_to<VisualShaderNodeBooleanUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_COLOR: {
+ if (!Object::cast_to<VisualShaderNodeColorUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_VEC3: {
+ if (!Object::cast_to<VisualShaderNodeVec3Uniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
+ if (!Object::cast_to<VisualShaderNodeTransformUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2D: {
+ if (!Object::cast_to<VisualShaderNodeTextureUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER3D: {
+ if (!Object::cast_to<VisualShaderNodeTexture3DUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: {
+ if (!Object::cast_to<VisualShaderNodeTexture2DArrayUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: {
+ if (!Object::cast_to<VisualShaderNodeCubemapUniform>(this)) {
+ incompatible_type = true;
+ }
+ } break;
+ default:
+ break;
+ }
+ if (incompatible_type) {
+ return vformat(TTR("Global uniform '%s' has an incompatible type for this kind of node.\nChange it in the Project Settings."), uniform_name);
+ }
}
return String();
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 6fd6fd8f3b..afe0bdfd5c 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -4575,7 +4575,10 @@ bool VisualShaderNodeTransformUniform::is_use_prop_slots() const {
}
bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) const {
- return true; // all qualifiers are supported
+ if (p_qual == Qualifier::QUAL_INSTANCE) {
+ return false;
+ }
+ return true;
}
bool VisualShaderNodeTransformUniform::is_convertible_to_constant() const {
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 4feaf08808..475f6c475d 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -9129,7 +9129,7 @@ RendererStorageRD::RendererStorageRD() {
} break;
case RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: {
sampler_state.mag_filter = RD::SAMPLER_FILTER_NEAREST;
- sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
+ sampler_state.min_filter = RD::SAMPLER_FILTER_NEAREST;
if (GLOBAL_GET("rendering/textures/default_filters/use_nearest_mipmap_filter")) {
sampler_state.mip_filter = RD::SAMPLER_FILTER_NEAREST;
} else {
@@ -9148,7 +9148,7 @@ RendererStorageRD::RendererStorageRD() {
} break;
case RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: {
sampler_state.mag_filter = RD::SAMPLER_FILTER_NEAREST;
- sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
+ sampler_state.min_filter = RD::SAMPLER_FILTER_NEAREST;
if (GLOBAL_GET("rendering/textures/default_filters/use_nearest_mipmap_filter")) {
sampler_state.mip_filter = RD::SAMPLER_FILTER_NEAREST;
} else {