Reorganize Output dock

This commit is contained in:
kobewi 2025-12-04 13:54:14 +01:00
parent d103efb6ea
commit 42da4512c6
4 changed files with 55 additions and 87 deletions

View file

@ -48,6 +48,7 @@
#include "editor/themes/editor_scale.h"
#include "modules/regex/regex.h"
#include "scene/gui/box_container.h"
#include "scene/gui/flow_container.h"
#include "scene/gui/separator.h"
#include "scene/main/timer.h"
#include "scene/resources/font.h"
@ -111,20 +112,23 @@ void EditorLog::_update_theme() {
log->add_theme_font_size_override("mono_font_size", font_size);
log->end_bulk_theme_override();
type_filter_map[MSG_TYPE_STD]->toggle_button->set_button_icon(get_editor_theme_icon(SNAME("Popup")));
type_filter_map[MSG_TYPE_ERROR]->toggle_button->set_button_icon(get_editor_theme_icon(SNAME("StatusError")));
type_filter_map[MSG_TYPE_WARNING]->toggle_button->set_button_icon(get_editor_theme_icon(SNAME("StatusWarning")));
type_filter_map[MSG_TYPE_EDITOR]->toggle_button->set_button_icon(get_editor_theme_icon(SNAME("Edit")));
const String wide_text = "MMM";
type_filter_map[MSG_TYPE_STD]->toggle_button->set_theme_type_variation("EditorLogFilterButton");
type_filter_map[MSG_TYPE_ERROR]->toggle_button->set_theme_type_variation("EditorLogFilterButton");
type_filter_map[MSG_TYPE_WARNING]->toggle_button->set_theme_type_variation("EditorLogFilterButton");
type_filter_map[MSG_TYPE_EDITOR]->toggle_button->set_theme_type_variation("EditorLogFilterButton");
Button *button = type_filter_map[MSG_TYPE_STD]->toggle_button;
button->set_button_icon(get_editor_theme_icon(SNAME("Popup")));
button->set_custom_minimum_size(button->get_minimum_size_for_text_and_icon(wide_text, button->get_button_icon()) * EDSCALE);
button = type_filter_map[MSG_TYPE_ERROR]->toggle_button;
button->set_button_icon(get_editor_theme_icon(SNAME("StatusError")));
button->set_custom_minimum_size(button->get_minimum_size_for_text_and_icon(wide_text, button->get_button_icon()) * EDSCALE);
button = type_filter_map[MSG_TYPE_WARNING]->toggle_button;
button->set_button_icon(get_editor_theme_icon(SNAME("StatusWarning")));
button->set_custom_minimum_size(button->get_minimum_size_for_text_and_icon(wide_text, button->get_button_icon()) * EDSCALE);
button = type_filter_map[MSG_TYPE_EDITOR]->toggle_button;
button->set_button_icon(get_editor_theme_icon(SNAME("Edit")));
button->set_custom_minimum_size(button->get_minimum_size_for_text_and_icon(wide_text, button->get_button_icon()) * EDSCALE);
clear_button->set_button_icon(get_editor_theme_icon(SNAME("Clear")));
copy_button->set_button_icon(get_editor_theme_icon(SNAME("ActionCopy")));
collapse_button->set_button_icon(get_editor_theme_icon(SNAME("CombineLines")));
show_search_button->set_button_icon(get_editor_theme_icon(SNAME("Search")));
search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
theme_cache.error_color = get_theme_color(SNAME("error_color"), EditorStringName(Editor));
@ -156,6 +160,17 @@ void EditorLog::_notification(int p_what) {
}
}
void EditorLog::shortcut_input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed() && !key->is_echo()) {
if (ED_IS_SHORTCUT("editor/open_search", p_event)) {
search_box->grab_focus();
search_box->select_all();
accept_event();
}
}
}
void EditorLog::_set_collapse(bool p_collapse) {
collapse = p_collapse;
_start_state_save_timer();
@ -180,7 +195,6 @@ void EditorLog::_save_state() {
}
config->set_value(section, "collapse", collapse);
config->set_value(section, "show_search", search_box->is_visible());
config->save(EditorPaths::get_singleton()->get_project_settings_dir().path_join("editor_layout.cfg"));
}
@ -200,9 +214,6 @@ void EditorLog::_load_state() {
collapse = config->get_value(section, "collapse", false);
collapse_button->set_pressed(collapse);
bool show_search = config->get_value(section, "show_search", true);
search_box->set_visible(show_search);
show_search_button->set_pressed(show_search);
is_loading_state = false;
}
@ -244,18 +255,6 @@ void EditorLog::_clear_request() {
_set_dock_tab_icon(Ref<Texture2D>());
}
void EditorLog::_copy_request() {
String text = log->get_selected_text();
if (text.is_empty()) {
text = log->get_parsed_text();
}
if (!text.is_empty()) {
DisplayServer::get_singleton()->clipboard_set(text);
}
}
void EditorLog::clear() {
_clear_request();
}
@ -473,14 +472,6 @@ void EditorLog::_set_filter_active(bool p_active, MessageType p_message_type) {
_rebuild_log();
}
void EditorLog::_set_search_visible(bool p_visible) {
search_box->set_visible(p_visible);
if (p_visible) {
search_box->grab_focus();
}
_start_state_save_timer();
}
void EditorLog::_search_changed(const String &p_text) {
_rebuild_log();
}
@ -497,6 +488,8 @@ EditorLog::EditorLog() {
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_output_bottom_panel", TTRC("Toggle Output Dock"), KeyModifierMask::ALT | Key::O));
set_default_slot(EditorDock::DOCK_SLOT_BOTTOM);
set_available_layouts(EditorDock::DOCK_LAYOUT_HORIZONTAL | EditorDock::DOCK_LAYOUT_FLOATING);
set_process_shortcut_input(true);
set_shortcut_context(this);
save_state_timer = memnew(Timer);
save_state_timer->set_wait_time(2);
@ -511,7 +504,7 @@ EditorLog::EditorLog() {
add_child(hb);
VBoxContainer *vb_left = memnew(VBoxContainer);
vb_left->set_custom_minimum_size(Size2(0, 180) * EDSCALE);
vb_left->set_custom_minimum_size(Size2(0, 90 * EDSCALE));
vb_left->set_v_size_flags(SIZE_EXPAND_FILL);
vb_left->set_h_size_flags(SIZE_EXPAND_FILL);
hb->add_child(vb_left);
@ -530,23 +523,22 @@ EditorLog::EditorLog() {
log->connect("meta_clicked", callable_mp(this, &EditorLog::_meta_clicked));
vb_left->add_child(log);
HFlowContainer *bottom_hf = memnew(HFlowContainer);
vb_left->add_child(bottom_hf);
HBoxContainer *hbox = memnew(HBoxContainer);
hbox->set_h_size_flags(SIZE_EXPAND_FILL);
bottom_hf->add_child(hbox);
// Search box
search_box = memnew(LineEdit);
search_box->set_custom_minimum_size(Vector2(200 * EDSCALE, 0));
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search_box->set_placeholder(TTR("Filter Messages"));
search_box->set_placeholder(TTRC("Filter Messages"));
search_box->set_accessibility_name(TTRC("Filter Messages"));
search_box->set_clear_button_enabled(true);
search_box->set_visible(true);
search_box->connect(SceneStringName(text_changed), callable_mp(this, &EditorLog::_search_changed));
vb_left->add_child(search_box);
VBoxContainer *vb_right = memnew(VBoxContainer);
hb->add_child(vb_right);
// Tools grid
HBoxContainer *hb_tools = memnew(HBoxContainer);
hb_tools->set_h_size_flags(SIZE_SHRINK_CENTER);
vb_right->add_child(hb_tools);
hbox->add_child(search_box);
// Clear.
clear_button = memnew(Button);
@ -555,25 +547,13 @@ EditorLog::EditorLog() {
clear_button->set_focus_mode(FOCUS_ACCESSIBILITY);
clear_button->set_shortcut(ED_SHORTCUT("editor/clear_output", TTRC("Clear Output"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::ALT | Key::K));
clear_button->connect(SceneStringName(pressed), callable_mp(this, &EditorLog::_clear_request));
hb_tools->add_child(clear_button);
// Copy.
copy_button = memnew(Button);
copy_button->set_accessibility_name(TTRC("Copy Selection"));
copy_button->set_theme_type_variation(SceneStringName(FlatButton));
copy_button->set_focus_mode(FOCUS_ACCESSIBILITY);
copy_button->set_shortcut(ED_SHORTCUT("editor/copy_output", TTRC("Copy Selection"), KeyModifierMask::CMD_OR_CTRL | Key::C));
copy_button->set_shortcut_context(this);
copy_button->connect(SceneStringName(pressed), callable_mp(this, &EditorLog::_copy_request));
hb_tools->add_child(copy_button);
hbox->add_child(clear_button);
// Separate toggle buttons from normal buttons.
vb_right->add_child(memnew(HSeparator));
hbox->add_child(memnew(VSeparator));
// A second hbox to make a 2x2 grid of buttons.
HBoxContainer *hb_tools2 = memnew(HBoxContainer);
hb_tools2->set_h_size_flags(SIZE_SHRINK_CENTER);
vb_right->add_child(hb_tools2);
hbox = memnew(HBoxContainer);
bottom_hf->add_child(hbox);
// Collapse.
collapse_button = memnew(Button);
@ -583,42 +563,28 @@ EditorLog::EditorLog() {
collapse_button->set_toggle_mode(true);
collapse_button->set_pressed(false);
collapse_button->connect(SceneStringName(toggled), callable_mp(this, &EditorLog::_set_collapse));
hb_tools2->add_child(collapse_button);
// Show Search.
show_search_button = memnew(Button);
show_search_button->set_accessibility_name(TTRC("Show Search"));
show_search_button->set_theme_type_variation(SceneStringName(FlatButton));
show_search_button->set_focus_mode(FOCUS_ACCESSIBILITY);
show_search_button->set_toggle_mode(true);
show_search_button->set_pressed(true);
show_search_button->set_shortcut(ED_SHORTCUT("editor/open_search", TTRC("Focus Search/Filter Bar"), KeyModifierMask::CMD_OR_CTRL | Key::F));
show_search_button->set_shortcut_context(this);
show_search_button->connect(SceneStringName(toggled), callable_mp(this, &EditorLog::_set_search_visible));
hb_tools2->add_child(show_search_button);
hbox->add_child(collapse_button);
// Message Type Filters.
vb_right->add_child(memnew(HSeparator));
LogFilter *std_filter = memnew(LogFilter(MSG_TYPE_STD));
std_filter->initialize_button(TTRC("Standard Messages"), TTRC("Toggle visibility of standard output messages."), callable_mp(this, &EditorLog::_set_filter_active));
vb_right->add_child(std_filter->toggle_button);
hbox->add_child(std_filter->toggle_button);
type_filter_map.insert(MSG_TYPE_STD, std_filter);
type_filter_map.insert(MSG_TYPE_STD_RICH, std_filter);
LogFilter *error_filter = memnew(LogFilter(MSG_TYPE_ERROR));
error_filter->initialize_button(TTRC("Errors"), TTRC("Toggle visibility of errors."), callable_mp(this, &EditorLog::_set_filter_active));
vb_right->add_child(error_filter->toggle_button);
hbox->add_child(error_filter->toggle_button);
type_filter_map.insert(MSG_TYPE_ERROR, error_filter);
LogFilter *warning_filter = memnew(LogFilter(MSG_TYPE_WARNING));
warning_filter->initialize_button(TTRC("Warnings"), TTRC("Toggle visibility of warnings."), callable_mp(this, &EditorLog::_set_filter_active));
vb_right->add_child(warning_filter->toggle_button);
hbox->add_child(warning_filter->toggle_button);
type_filter_map.insert(MSG_TYPE_WARNING, warning_filter);
LogFilter *editor_filter = memnew(LogFilter(MSG_TYPE_EDITOR));
editor_filter->initialize_button(TTRC("Editor Messages"), TTRC("Toggle visibility of editor messages."), callable_mp(this, &EditorLog::_set_filter_active));
vb_right->add_child(editor_filter->toggle_button);
hbox->add_child(editor_filter->toggle_button);
type_filter_map.insert(MSG_TYPE_EDITOR, editor_filter);
add_message(GODOT_VERSION_FULL_NAME " (c) 2007-present Juan Linietsky, Ariel Manzur & Godot Contributors.");
@ -626,6 +592,8 @@ EditorLog::EditorLog() {
eh.errfunc = _error_handler;
eh.userdata = this;
add_error_handler(&eh);
ED_SHORTCUT("editor/open_search", TTRC("Focus Search/Filter Bar"), KeyModifierMask::CMD_OR_CTRL | Key::F);
}
void EditorLog::deinit() {

View file

@ -96,6 +96,7 @@ private:
toggle_button->set_accessibility_name(TTRGET(p_name));
toggle_button->set_tooltip_text(TTRGET(p_tooltip));
toggle_button->set_focus_mode(FOCUS_ACCESSIBILITY);
toggle_button->set_theme_type_variation("EditorLogFilterButton");
// When toggled call the callback and pass the MessageType this button is for.
toggle_button->connect(SceneStringName(toggled), p_toggled_callback.bind(type));
}
@ -132,12 +133,10 @@ private:
RichTextLabel *log = nullptr;
Button *clear_button = nullptr;
Button *copy_button = nullptr;
Button *collapse_button = nullptr;
bool collapse = false;
Button *show_search_button = nullptr;
LineEdit *search_box = nullptr;
// Reusable RichTextLabel for BBCode parsing during search
@ -153,7 +152,6 @@ private:
//void _dragged(const Point2& p_ofs);
void _meta_clicked(const String &p_meta);
void _clear_request();
void _copy_request();
static void _undo_redo_cbk(void *p_self, const String &p_name);
void _rebuild_log();
@ -161,7 +159,6 @@ private:
bool _check_display_message(LogMessage &p_message);
void _set_filter_active(bool p_active, MessageType p_message_type);
void _set_search_visible(bool p_visible);
void _search_changed(const String &p_text);
void _process_message(const String &p_msg, MessageType p_type, bool p_clear);
@ -179,6 +176,7 @@ private:
protected:
void _notification(int p_what);
virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
public:
void add_message(const String &p_msg, MessageType p_type = MSG_TYPE_STD);

View file

@ -9122,6 +9122,7 @@ EditorNode::EditorNode() {
{
Dictionary offsets;
offsets["Audio"] = -450;
offsets["Output"] = -270;
default_layout->set_value(EDITOR_NODE_CONFIG_SECTION, "bottom_panel_offsets", offsets);
}

View file

@ -41,6 +41,7 @@
#include "editor/scene/editor_scene_tabs.h"
#include "editor/settings/editor_command_palette.h"
#include "editor/settings/editor_settings.h"
#include "editor/themes/editor_scale.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/separator.h"
@ -151,7 +152,7 @@ void EditorBottomPanel::load_selected_tab(int p_idx) {
void EditorBottomPanel::save_layout_to_config(Ref<ConfigFile> p_config_file, const String &p_section) const {
Dictionary offsets;
for (const KeyValue<String, int> &E : dock_offsets) {
offsets[E.key] = E.value;
offsets[E.key] = E.value / EDSCALE;
}
p_config_file->set_value(p_section, "bottom_panel_offsets", offsets);
}
@ -161,7 +162,7 @@ void EditorBottomPanel::load_layout_from_config(Ref<ConfigFile> p_config_file, c
const LocalVector<Variant> offset_list = offsets.get_key_list();
for (const Variant &v : offset_list) {
dock_offsets[v] = offsets[v];
dock_offsets[v] = (int)offsets[v] * EDSCALE;
}
_update_center_split_offset();
}