1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Make shader editor menu position consistent between shader languages

This commit is contained in:
Aaron Franke
2025-08-25 15:55:30 -07:00
parent 17fb6e3bd0
commit 0831b4b516
7 changed files with 83 additions and 114 deletions

View File

@@ -33,16 +33,19 @@
#include "scene/gui/control.h"
#include "scene/resources/shader.h"
class Button;
class MenuButton;
class ShaderEditor : public Control {
GDCLASS(ShaderEditor, Control);
public:
virtual void edit_shader(const Ref<Shader> &p_shader) = 0;
virtual void edit_shader_include(const Ref<ShaderInclude> &p_shader_inc) {}
virtual void use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) = 0;
virtual void apply_shaders() = 0;
virtual bool is_unsaved() const = 0;
virtual void save_external_data(const String &p_str = "") = 0;
virtual void validate_script() = 0;
virtual Control *get_top_bar() = 0;
};

View File

@@ -190,12 +190,6 @@ void ShaderEditorPlugin::edit(Object *p_object) {
cte->connect("zoomed", callable_mp(this, &ShaderEditorPlugin::_set_text_shader_zoom_factor));
cte->connect(SceneStringName(visibility_changed), callable_mp(this, &ShaderEditorPlugin::_update_shader_editor_zoom_factor).bind(cte));
}
if (text_shader_editor->get_top_bar()) {
text_shader_editor->get_top_bar()->set_h_size_flags(Control::SIZE_EXPAND_FILL);
menu_hb->add_child(text_shader_editor->get_top_bar());
menu_hb->move_child(text_shader_editor->get_top_bar(), 1);
}
}
shader_tabs->set_current_tab(shader_tabs->get_tab_count() - 1);
@@ -459,29 +453,22 @@ void ShaderEditorPlugin::_make_script_list_context_menu() {
void ShaderEditorPlugin::_close_shader(int p_index) {
ERR_FAIL_INDEX(p_index, shader_tabs->get_tab_count());
Control *c = shader_tabs->get_tab_control(p_index);
VisualShaderEditor *vs_editor = Object::cast_to<VisualShaderEditor>(c);
if (vs_editor) {
vs_editor->save_editor_layout();
if (file_menu->get_parent() != nullptr) {
file_menu->get_parent()->remove_child(file_menu);
menu_hb->add_child(file_menu);
menu_hb->move_child(file_menu, 0);
make_floating->get_parent()->remove_child(make_floating);
menu_hb->add_child(make_floating);
} else {
memdelete(edited_shaders[p_index].shader_editor->get_top_bar());
}
if (make_floating->get_parent()) {
make_floating->get_parent()->remove_child(make_floating);
}
ShaderEditor *shader_editor = Object::cast_to<ShaderEditor>(shader_tabs->get_tab_control(p_index));
ERR_FAIL_NULL(shader_editor);
memdelete(c);
memdelete(shader_editor);
edited_shaders.remove_at(p_index);
_update_shader_list();
EditorUndoRedoManager::get_singleton()->clear_history(); // To prevent undo on deleted graphs.
if (shader_tabs->get_tab_count() == 0) {
shader_list->show(); // Make sure the panel is visible, because it can't be toggled without open shaders.
menu_spacer->show();
} else {
_switch_to_editor(edited_shaders[shader_tabs->get_current_tab()].shader_editor);
}
@@ -795,44 +782,13 @@ void ShaderEditorPlugin::_update_shader_editor_zoom_factor(CodeTextEditor *p_sha
}
void ShaderEditorPlugin::_switch_to_editor(ShaderEditor *p_editor) {
Control *bar = p_editor->get_top_bar();
VisualShaderEditor *vs_editor = Object::cast_to<VisualShaderEditor>(p_editor);
if (vs_editor) {
if (file_menu->get_parent() != nullptr) {
file_menu->get_parent()->remove_child(file_menu);
file_menu->set_switch_on_hover(false);
bar->add_child(file_menu);
bar->move_child(file_menu, 2); // Toggle Files Panel button + separator.
}
if (make_floating->get_parent()) {
make_floating->get_parent()->remove_child(make_floating);
bar->add_child(make_floating);
} else {
if (menu_spacer->is_visible()) {
menu_spacer->hide();
}
// Just swapped from a visual shader editor.
if (file_menu->get_parent() != menu_hb) {
file_menu->get_parent()->remove_child(file_menu);
file_menu->set_switch_on_hover(true);
menu_hb->add_child(file_menu);
menu_hb->move_child(file_menu, 0);
make_floating->get_parent()->remove_child(make_floating);
menu_hb->add_child(make_floating);
}
}
for (int i = 0; i < shader_tabs->get_tab_count(); i++) {
ShaderEditor *se = Object::cast_to<ShaderEditor>(shader_tabs->get_tab_control(i));
if (se && se->get_top_bar()) {
if (se == p_editor) {
se->get_top_bar()->show();
} else {
se->get_top_bar()->hide();
}
}
}
p_editor->use_menu_bar_items(file_menu, make_floating);
}
void ShaderEditorPlugin::_file_removed(const String &p_removed_file) {
@@ -902,8 +858,6 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
files_split->set_split_offset(200 * EDSCALE);
files_split->set_v_size_flags(Control::SIZE_EXPAND_FILL);
menu_hb = memnew(HBoxContainer);
main_container->add_child(menu_hb);
file_menu = memnew(MenuButton);
file_menu->set_flat(false);
file_menu->set_theme_type_variation("FlatMenuButton");
@@ -912,7 +866,6 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
file_menu->set_shortcut_context(files_split);
_setup_popup_menu(FILE, file_menu->get_popup());
file_menu->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed));
menu_hb->add_child(file_menu);
_set_file_specific_items_disabled(true);
@@ -920,8 +873,6 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
add_child(context_menu);
context_menu->connect(SceneStringName(id_pressed), callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed));
menu_spacer = menu_hb->add_spacer();
make_floating = memnew(ScreenSelect);
make_floating->connect("request_open_in_screen", callable_mp(window_wrapper, &WindowWrapper::enable_window_on_screen).bind(true));
if (!make_floating->is_disabled()) {
@@ -929,7 +880,6 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
make_floating->set_tooltip_text(TTR("Make the shader editor floating.") + "\n" + TTR("Right-click to open the screen selector."));
}
menu_hb->add_child(make_floating);
window_wrapper->connect("window_visibility_changed", callable_mp(this, &ShaderEditorPlugin::_window_changed));
shader_list = memnew(ItemList);
@@ -962,3 +912,8 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
shader_create_dialog->connect("shader_created", callable_mp(this, &ShaderEditorPlugin::_shader_created));
shader_create_dialog->connect("shader_include_created", callable_mp(this, &ShaderEditorPlugin::_shader_include_created));
}
ShaderEditorPlugin::~ShaderEditorPlugin() {
memdelete(file_menu);
memdelete(make_floating);
}

View File

@@ -83,8 +83,6 @@ class ShaderEditorPlugin : public EditorPlugin {
VBoxContainer *main_container = nullptr;
HSplitContainer *files_split = nullptr;
HBoxContainer *menu_hb = nullptr;
Control *menu_spacer = nullptr;
ItemList *shader_list = nullptr;
TabContainer *shader_tabs = nullptr;
@@ -150,4 +148,5 @@ public:
virtual void apply_changes() override;
ShaderEditorPlugin();
~ShaderEditorPlugin();
};

View File

@@ -979,6 +979,13 @@ void TextShaderEditor::edit_shader_include(const Ref<ShaderInclude> &p_shader_in
code_editor->set_edited_shader_include(p_shader_inc);
}
void TextShaderEditor::use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) {
p_file_menu->set_switch_on_hover(true);
menu_bar_hbox->add_child(p_file_menu);
menu_bar_hbox->move_child(p_file_menu, 0);
menu_bar_hbox->add_child(p_make_floating);
}
void TextShaderEditor::save_external_data(const String &p_str) {
if (shader.is_null() && shader_inc.is_null()) {
disk_changed->hide();
@@ -1027,10 +1034,6 @@ void TextShaderEditor::validate_script() {
code_editor->_validate_script();
}
Control *TextShaderEditor::get_top_bar() {
return hbc;
}
bool TextShaderEditor::is_unsaved() const {
return code_editor->get_text_editor()->get_saved_version() != code_editor->get_text_editor()->get_version();
}
@@ -1204,7 +1207,7 @@ TextShaderEditor::TextShaderEditor() {
VBoxContainer *main_container = memnew(VBoxContainer);
main_container->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
hbc = memnew(HBoxContainer);
menu_bar_hbox = memnew(HBoxContainer);
edit_menu = memnew(MenuButton);
edit_menu->set_flat(false);
@@ -1267,20 +1270,21 @@ TextShaderEditor::TextShaderEditor() {
bookmarks_menu->connect("index_pressed", callable_mp(this, &TextShaderEditor::_bookmark_item_pressed));
add_child(main_container);
hbc->add_child(edit_menu);
hbc->add_child(search_menu);
hbc->add_child(goto_menu);
hbc->add_spacer();
main_container->add_child(menu_bar_hbox);
menu_bar_hbox->add_child(edit_menu);
menu_bar_hbox->add_child(search_menu);
menu_bar_hbox->add_child(goto_menu);
menu_bar_hbox->add_spacer();
site_search = memnew(Button);
site_search->set_theme_type_variation(SceneStringName(FlatButton));
site_search->connect(SceneStringName(pressed), callable_mp(this, &TextShaderEditor::_menu_option).bind(HELP_DOCS));
site_search->set_text(TTR("Online Docs"));
site_search->set_tooltip_text(TTR("Open Godot online documentation."));
hbc->add_child(site_search);
hbc->add_child(memnew(VSeparator));
menu_bar_hbox->add_child(site_search);
menu_bar_hbox->add_child(memnew(VSeparator));
hbc->add_theme_style_override(SceneStringName(panel), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("ScriptEditorPanel"), EditorStringName(EditorStyles)));
menu_bar_hbox->add_theme_style_override(SceneStringName(panel), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("ScriptEditorPanel"), EditorStringName(EditorStyles)));
VSplitContainer *editor_box = memnew(VSplitContainer);
main_container->add_child(editor_box);

View File

@@ -136,7 +136,7 @@ class TextShaderEditor : public ShaderEditor {
EDIT_EMOJI_AND_SYMBOL,
};
HBoxContainer *hbc = nullptr;
HBoxContainer *menu_bar_hbox = nullptr;
MenuButton *edit_menu = nullptr;
MenuButton *search_menu = nullptr;
PopupMenu *bookmarks_menu = nullptr;
@@ -191,12 +191,12 @@ protected:
public:
virtual void edit_shader(const Ref<Shader> &p_shader) override;
virtual void edit_shader_include(const Ref<ShaderInclude> &p_shader_inc) override;
virtual void use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) override;
virtual void apply_shaders() override;
virtual bool is_unsaved() const override;
virtual void save_external_data(const String &p_str = "") override;
virtual void validate_script() override;
virtual Control *get_top_bar() override;
bool was_compilation_successful() const { return compilation_success; }
bool get_trim_trailing_whitespace_on_save() const { return trim_trailing_whitespace_on_save; }

View File

@@ -1560,6 +1560,13 @@ void VisualShaderEditor::edit_shader(const Ref<Shader> &p_shader) {
}
}
void VisualShaderEditor::use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) {
p_file_menu->set_switch_on_hover(false);
toolbar_hflow->add_child(p_file_menu);
toolbar_hflow->move_child(p_file_menu, 2); // Toggle Files Panel button + separator.
toolbar_hflow->add_child(p_make_floating);
}
void VisualShaderEditor::apply_shaders() {
// Stub. TODO: Implement apply_shaders in visual shaders for parity with text shaders.
}
@@ -1610,10 +1617,6 @@ VisualShader::Type VisualShaderEditor::get_current_shader_type() const {
return current_type;
}
Control *VisualShaderEditor::get_top_bar() {
return toolbar;
}
void VisualShaderEditor::add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin) {
if (plugins.has(p_plugin)) {
return;
@@ -6607,7 +6610,7 @@ VisualShaderEditor::VisualShaderEditor() {
toolbar_panel->set_anchors_and_offsets_preset(Control::PRESET_TOP_WIDE, PRESET_MODE_MINSIZE, 10);
toolbar_panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
toolbar = memnew(HFlowContainer);
toolbar_hflow = memnew(HFlowContainer);
{
LocalVector<Node *> nodes;
for (int i = 0; i < graph->get_menu_hbox()->get_child_count(); i++) {
@@ -6617,16 +6620,16 @@ VisualShaderEditor::VisualShaderEditor() {
for (Node *node : nodes) {
graph->get_menu_hbox()->remove_child(node);
toolbar->add_child(node);
toolbar_hflow->add_child(node);
}
graph->get_menu_hbox()->hide();
toolbar_panel->add_child(toolbar);
toolbar_panel->add_child(toolbar_hflow);
}
VSeparator *vs = memnew(VSeparator);
toolbar->add_child(vs);
toolbar->move_child(vs, 0);
toolbar_hflow->add_child(vs);
toolbar_hflow->move_child(vs, 0);
custom_mode_box = memnew(CheckBox);
custom_mode_box->set_text(TTR("Custom"));
@@ -6660,22 +6663,22 @@ VisualShaderEditor::VisualShaderEditor() {
edit_type = edit_type_standard;
toolbar->add_child(custom_mode_box);
toolbar->move_child(custom_mode_box, 0);
toolbar->add_child(edit_type_standard);
toolbar->move_child(edit_type_standard, 0);
toolbar->add_child(edit_type_particles);
toolbar->move_child(edit_type_particles, 0);
toolbar->add_child(edit_type_sky);
toolbar->move_child(edit_type_sky, 0);
toolbar->add_child(edit_type_fog);
toolbar->move_child(edit_type_fog, 0);
toolbar_hflow->add_child(custom_mode_box);
toolbar_hflow->move_child(custom_mode_box, 0);
toolbar_hflow->add_child(edit_type_standard);
toolbar_hflow->move_child(edit_type_standard, 0);
toolbar_hflow->add_child(edit_type_particles);
toolbar_hflow->move_child(edit_type_particles, 0);
toolbar_hflow->add_child(edit_type_sky);
toolbar_hflow->move_child(edit_type_sky, 0);
toolbar_hflow->add_child(edit_type_fog);
toolbar_hflow->move_child(edit_type_fog, 0);
add_node = memnew(Button);
add_node->set_theme_type_variation(SceneStringName(FlatButton));
add_node->set_text(TTR("Add Node..."));
toolbar->add_child(add_node);
toolbar->move_child(add_node, 0);
toolbar_hflow->add_child(add_node);
toolbar_hflow->move_child(add_node, 0);
add_node->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_show_members_dialog).bind(false, VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PORT_TYPE_MAX));
graph->connect("graph_elements_linked_to_frame_request", callable_mp(this, &VisualShaderEditor::_nodes_linked_to_frame_request));
@@ -6686,7 +6689,7 @@ VisualShaderEditor::VisualShaderEditor() {
varying_button->set_theme_type_variation("FlatMenuButton");
varying_button->set_text(TTR("Manage Varyings"));
varying_button->set_switch_on_hover(true);
toolbar->add_child(varying_button);
toolbar_hflow->add_child(varying_button);
PopupMenu *varying_menu = varying_button->get_popup();
varying_menu->add_item(TTR("Add Varying"), int(VaryingMenuOptions::ADD));
@@ -6697,7 +6700,7 @@ VisualShaderEditor::VisualShaderEditor() {
code_preview_button->set_theme_type_variation(SceneStringName(FlatButton));
code_preview_button->set_toggle_mode(true);
code_preview_button->set_tooltip_text(TTR("Show generated shader code."));
toolbar->add_child(code_preview_button);
toolbar_hflow->add_child(code_preview_button);
code_preview_button->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_show_preview_text));
shader_preview_button = memnew(Button);
@@ -6705,34 +6708,34 @@ VisualShaderEditor::VisualShaderEditor() {
shader_preview_button->set_toggle_mode(true);
shader_preview_button->set_tooltip_text(TTR("Toggle shader preview."));
shader_preview_button->set_pressed(true);
toolbar->add_child(shader_preview_button);
toolbar_hflow->add_child(shader_preview_button);
shader_preview_button->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_show_shader_preview));
Control *spacer = memnew(Control);
spacer->set_h_size_flags(Control::SIZE_EXPAND);
toolbar->add_child(spacer);
toolbar_hflow->add_child(spacer);
site_search = memnew(Button);
site_search->set_theme_type_variation(SceneStringName(FlatButton));
site_search->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_help_open));
site_search->set_text(TTR("Online Docs"));
site_search->set_tooltip_text(TTR("Open Godot online documentation."));
toolbar->add_child(site_search);
toolbar->add_child(memnew(VSeparator));
toolbar_hflow->add_child(site_search);
toolbar_hflow->add_child(memnew(VSeparator));
VSeparator *separator = memnew(VSeparator);
toolbar->add_child(separator);
toolbar->move_child(separator, 0);
toolbar_hflow->add_child(separator);
toolbar_hflow->move_child(separator, 0);
separator = memnew(VSeparator);
toolbar->add_child(separator);
toolbar->move_child(separator, 0);
toolbar_hflow->add_child(separator);
toolbar_hflow->move_child(separator, 0);
toggle_files_button = memnew(Button);
toggle_files_button->set_theme_type_variation(SceneStringName(FlatButton));
toggle_files_button->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_toggle_files_pressed));
toolbar->add_child(toggle_files_button);
toolbar->move_child(toggle_files_button, 0);
toolbar_hflow->add_child(toggle_files_button);
toolbar_hflow->move_child(toggle_files_button, 0);
///////////////////////////////////////
// CODE PREVIEW
@@ -7761,6 +7764,10 @@ VisualShaderEditor::VisualShaderEditor() {
add_child(panning_debounce_timer);
}
VisualShaderEditor::~VisualShaderEditor() {
save_editor_layout();
}
class VisualShaderNodePluginInputEditor : public OptionButton {
GDCLASS(VisualShaderNodePluginInputEditor, OptionButton);

View File

@@ -43,6 +43,7 @@ class ColorPicker;
class CurveEditor;
class GraphElement;
class GraphFrame;
class HFlowContainer;
class MenuButton;
class PopupPanel;
class RichTextLabel;
@@ -220,7 +221,7 @@ class VisualShaderEditor : public ShaderEditor {
MenuButton *varying_button = nullptr;
Button *code_preview_button = nullptr;
Button *shader_preview_button = nullptr;
Control *toolbar = nullptr;
HFlowContainer *toolbar_hflow = nullptr;
int last_to_node = -1;
int last_to_port = -1;
@@ -650,6 +651,7 @@ protected:
public:
virtual void edit_shader(const Ref<Shader> &p_shader) override;
virtual void use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) override;
virtual void apply_shaders() override;
virtual bool is_unsaved() const override;
virtual void save_external_data(const String &p_str = "") override;
@@ -660,8 +662,6 @@ public:
void set_current_shader_type(VisualShader::Type p_type);
VisualShader::Type get_current_shader_type() const;
virtual Control *get_top_bar() override;
void add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
void remove_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
@@ -680,6 +680,7 @@ public:
Ref<VisualShader> get_visual_shader() const { return visual_shader; }
VisualShaderEditor();
~VisualShaderEditor();
};
class VisualShaderNodePluginDefault : public VisualShaderNodePlugin {