2024-08-19 22:08:31 +00:00
|
|
|
/**************************************************************************/
|
|
|
|
/* editor_main_screen.cpp */
|
|
|
|
/**************************************************************************/
|
|
|
|
/* This file is part of: */
|
|
|
|
/* GODOT ENGINE */
|
|
|
|
/* https://godotengine.org */
|
|
|
|
/**************************************************************************/
|
|
|
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
|
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
|
|
/* */
|
|
|
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
|
|
/* a copy of this software and associated documentation files (the */
|
|
|
|
/* "Software"), to deal in the Software without restriction, including */
|
|
|
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
|
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
|
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
|
|
/* the following conditions: */
|
|
|
|
/* */
|
|
|
|
/* The above copyright notice and this permission notice shall be */
|
|
|
|
/* included in all copies or substantial portions of the Software. */
|
|
|
|
/* */
|
|
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
|
|
#include "editor_main_screen.h"
|
|
|
|
|
|
|
|
#include "core/io/config_file.h"
|
|
|
|
#include "editor/editor_node.h"
|
|
|
|
#include "editor/editor_settings.h"
|
|
|
|
#include "editor/editor_string_names.h"
|
|
|
|
#include "editor/plugins/editor_plugin.h"
|
|
|
|
#include "scene/gui/box_container.h"
|
|
|
|
#include "scene/gui/button.h"
|
|
|
|
|
|
|
|
void EditorMainScreen::_notification(int p_what) {
|
|
|
|
switch (p_what) {
|
|
|
|
case NOTIFICATION_READY: {
|
|
|
|
if (EDITOR_3D < buttons.size() && buttons[EDITOR_3D]->is_visible()) {
|
|
|
|
// If the 3D editor is enabled, use this as the default.
|
|
|
|
select(EDITOR_3D);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Switch to the first main screen plugin that is enabled. Usually this is
|
|
|
|
// 2D, but may be subsequent ones if 2D is disabled in the feature profile.
|
|
|
|
for (int i = 0; i < buttons.size(); i++) {
|
|
|
|
Button *editor_button = buttons[i];
|
|
|
|
if (editor_button->is_visible()) {
|
|
|
|
select(i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
select(-1);
|
|
|
|
} break;
|
|
|
|
case NOTIFICATION_THEME_CHANGED: {
|
|
|
|
for (int i = 0; i < buttons.size(); i++) {
|
|
|
|
Button *tb = buttons[i];
|
|
|
|
EditorPlugin *p_editor = editor_table[i];
|
|
|
|
Ref<Texture2D> icon = p_editor->get_icon();
|
|
|
|
|
|
|
|
if (icon.is_valid()) {
|
2024-10-09 22:21:47 +00:00
|
|
|
tb->set_button_icon(icon);
|
2024-08-19 22:08:31 +00:00
|
|
|
} else if (has_theme_icon(p_editor->get_name(), EditorStringName(EditorIcons))) {
|
2024-10-09 22:21:47 +00:00
|
|
|
tb->set_button_icon(get_theme_icon(p_editor->get_name(), EditorStringName(EditorIcons)));
|
2024-08-19 22:08:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::set_button_container(HBoxContainer *p_button_hb) {
|
|
|
|
button_hb = p_button_hb;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::save_layout_to_config(Ref<ConfigFile> p_config_file, const String &p_section) const {
|
|
|
|
int selected_main_editor_idx = -1;
|
|
|
|
for (int i = 0; i < buttons.size(); i++) {
|
|
|
|
if (buttons[i]->is_pressed()) {
|
|
|
|
selected_main_editor_idx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (selected_main_editor_idx != -1) {
|
|
|
|
p_config_file->set_value(p_section, "selected_main_editor_idx", selected_main_editor_idx);
|
|
|
|
} else {
|
|
|
|
p_config_file->set_value(p_section, "selected_main_editor_idx", Variant());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::load_layout_from_config(Ref<ConfigFile> p_config_file, const String &p_section) {
|
|
|
|
int selected_main_editor_idx = p_config_file->get_value(p_section, "selected_main_editor_idx", -1);
|
|
|
|
if (selected_main_editor_idx >= 0 && selected_main_editor_idx < buttons.size()) {
|
|
|
|
callable_mp(this, &EditorMainScreen::select).call_deferred(selected_main_editor_idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::set_button_enabled(int p_index, bool p_enabled) {
|
|
|
|
ERR_FAIL_INDEX(p_index, buttons.size());
|
|
|
|
buttons[p_index]->set_visible(p_enabled);
|
|
|
|
if (!p_enabled && buttons[p_index]->is_pressed()) {
|
|
|
|
select(EDITOR_2D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EditorMainScreen::is_button_enabled(int p_index) const {
|
|
|
|
ERR_FAIL_INDEX_V(p_index, buttons.size(), false);
|
|
|
|
return buttons[p_index]->is_visible();
|
|
|
|
}
|
|
|
|
|
|
|
|
int EditorMainScreen::_get_current_main_editor() const {
|
|
|
|
for (int i = 0; i < editor_table.size(); i++) {
|
|
|
|
if (editor_table[i] == selected_plugin) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::select_next() {
|
|
|
|
int editor = _get_current_main_editor();
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (editor == editor_table.size() - 1) {
|
|
|
|
editor = 0;
|
|
|
|
} else {
|
|
|
|
editor++;
|
|
|
|
}
|
|
|
|
} while (!buttons[editor]->is_visible());
|
|
|
|
|
|
|
|
select(editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::select_prev() {
|
|
|
|
int editor = _get_current_main_editor();
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (editor == 0) {
|
|
|
|
editor = editor_table.size() - 1;
|
|
|
|
} else {
|
|
|
|
editor--;
|
|
|
|
}
|
|
|
|
} while (!buttons[editor]->is_visible());
|
|
|
|
|
|
|
|
select(editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::select_by_name(const String &p_name) {
|
|
|
|
ERR_FAIL_COND(p_name.is_empty());
|
|
|
|
|
|
|
|
for (int i = 0; i < buttons.size(); i++) {
|
|
|
|
if (buttons[i]->get_text() == p_name) {
|
|
|
|
select(i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ERR_FAIL_MSG("The editor name '" + p_name + "' was not found.");
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::select(int p_index) {
|
|
|
|
if (EditorNode::get_singleton()->is_changing_scene()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ERR_FAIL_INDEX(p_index, editor_table.size());
|
|
|
|
|
|
|
|
if (!buttons[p_index]->is_visible()) { // Button hidden, no editor.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < buttons.size(); i++) {
|
|
|
|
buttons[i]->set_pressed_no_signal(i == p_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
EditorPlugin *new_editor = editor_table[p_index];
|
|
|
|
ERR_FAIL_NULL(new_editor);
|
|
|
|
|
|
|
|
if (selected_plugin == new_editor) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected_plugin) {
|
|
|
|
selected_plugin->make_visible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
selected_plugin = new_editor;
|
|
|
|
selected_plugin->make_visible(true);
|
|
|
|
selected_plugin->selected_notify();
|
|
|
|
|
|
|
|
EditorData &editor_data = EditorNode::get_editor_data();
|
|
|
|
int plugin_count = editor_data.get_editor_plugin_count();
|
|
|
|
for (int i = 0; i < plugin_count; i++) {
|
|
|
|
editor_data.get_editor_plugin(i)->notify_main_screen_changed(selected_plugin->get_name());
|
|
|
|
}
|
|
|
|
|
|
|
|
EditorNode::get_singleton()->update_distraction_free_mode();
|
|
|
|
}
|
|
|
|
|
|
|
|
int EditorMainScreen::get_selected_index() const {
|
|
|
|
for (int i = 0; i < editor_table.size(); i++) {
|
|
|
|
if (selected_plugin == editor_table[i]) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int EditorMainScreen::get_plugin_index(EditorPlugin *p_editor) const {
|
|
|
|
int screen = -1;
|
|
|
|
for (int i = 0; i < editor_table.size(); i++) {
|
|
|
|
if (p_editor == editor_table[i]) {
|
|
|
|
screen = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return screen;
|
|
|
|
}
|
|
|
|
|
|
|
|
EditorPlugin *EditorMainScreen::get_selected_plugin() const {
|
|
|
|
return selected_plugin;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBoxContainer *EditorMainScreen::get_control() const {
|
|
|
|
return main_screen_vbox;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::add_main_plugin(EditorPlugin *p_editor) {
|
|
|
|
Button *tb = memnew(Button);
|
|
|
|
tb->set_toggle_mode(true);
|
|
|
|
tb->set_theme_type_variation("MainScreenButton");
|
|
|
|
tb->set_name(p_editor->get_name());
|
|
|
|
tb->set_text(p_editor->get_name());
|
|
|
|
|
|
|
|
Ref<Texture2D> icon = p_editor->get_icon();
|
|
|
|
if (icon.is_null() && has_theme_icon(p_editor->get_name(), EditorStringName(EditorIcons))) {
|
|
|
|
icon = get_editor_theme_icon(p_editor->get_name());
|
|
|
|
}
|
|
|
|
if (icon.is_valid()) {
|
2024-10-09 22:21:47 +00:00
|
|
|
tb->set_button_icon(icon);
|
2024-08-19 22:08:31 +00:00
|
|
|
// Make sure the control is updated if the icon is reimported.
|
|
|
|
icon->connect_changed(callable_mp((Control *)tb, &Control::update_minimum_size));
|
|
|
|
}
|
|
|
|
|
|
|
|
tb->connect(SceneStringName(pressed), callable_mp(this, &EditorMainScreen::select).bind(buttons.size()));
|
|
|
|
|
|
|
|
buttons.push_back(tb);
|
|
|
|
button_hb->add_child(tb);
|
|
|
|
editor_table.push_back(p_editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditorMainScreen::remove_main_plugin(EditorPlugin *p_editor) {
|
|
|
|
// Remove the main editor button and update the bindings of
|
|
|
|
// all buttons behind it to point to the correct main window.
|
|
|
|
for (int i = buttons.size() - 1; i >= 0; i--) {
|
|
|
|
if (p_editor->get_name() == buttons[i]->get_text()) {
|
|
|
|
if (buttons[i]->is_pressed()) {
|
|
|
|
select(EDITOR_SCRIPT);
|
|
|
|
}
|
|
|
|
|
|
|
|
memdelete(buttons[i]);
|
|
|
|
buttons.remove_at(i);
|
|
|
|
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
buttons[i]->disconnect(SceneStringName(pressed), callable_mp(this, &EditorMainScreen::select));
|
|
|
|
buttons[i]->connect(SceneStringName(pressed), callable_mp(this, &EditorMainScreen::select).bind(i - 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected_plugin == p_editor) {
|
|
|
|
selected_plugin = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
editor_table.erase(p_editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
EditorMainScreen::EditorMainScreen() {
|
|
|
|
main_screen_vbox = memnew(VBoxContainer);
|
|
|
|
main_screen_vbox->set_name("MainScreen");
|
|
|
|
main_screen_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
|
|
|
main_screen_vbox->add_theme_constant_override("separation", 0);
|
|
|
|
add_child(main_screen_vbox);
|
|
|
|
}
|