diff --git a/doc/classes/EditorDock.xml b/doc/classes/EditorDock.xml
index e8926c96fd3..d0ab092fc8d 100644
--- a/doc/classes/EditorDock.xml
+++ b/doc/classes/EditorDock.xml
@@ -85,7 +85,6 @@
The available layouts for this dock, as a bitmask. By default, the dock allows vertical and floating layouts.
-
If [code]true[/code], the dock can be closed with the Close button in the context popup. Docks with [member global] enabled are always closable.
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index b6b3f8f324b..47f715ba48b 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -421,12 +421,18 @@
Whether all columns will have the same width.
If [code]true[/code], the width is equal to the largest column width of all columns.
+
+ The way which scroll hints (indicators that show that the content can still be scrolled in a certain direction) will be shown.
+
Allows single or multiple item selection. See the [enum SelectMode] constants.
The clipping behavior when the text exceeds an item's bounding rectangle.
+
+ If [code]true[/code], the scroll hint texture will be tiled instead of stretched. See [member scroll_hint_mode].
+
If [code]true[/code], the control will automatically move items into a new row to fit its content. See also [HFlowContainer] for this behavior.
If [code]false[/code], the control will add a horizontal scrollbar to make all items visible.
@@ -487,6 +493,18 @@
Allows selecting multiple items by toggling them on and off.
+
+ Scroll hints will never be shown.
+
+
+ Scroll hints will be shown at the top and bottom.
+
+
+ Only the top scroll hint will be shown.
+
+
+ Only the bottom scroll hint will be shown.
+
@@ -529,6 +547,9 @@
Font size of the item's text.
+
+ The indicator that will be shown when the content can still be scrolled. See [member scroll_hint_mode].
+
[StyleBox] used for the cursor, when the [ItemList] is being focused.
diff --git a/editor/animation/animation_track_editor.cpp b/editor/animation/animation_track_editor.cpp
index 44ded4d0f1c..b70e47befb1 100644
--- a/editor/animation/animation_track_editor.cpp
+++ b/editor/animation/animation_track_editor.cpp
@@ -7879,6 +7879,16 @@ float AnimationTrackEditor::get_snap_unit() {
return snap_unit;
}
+void AnimationTrackEditor::_update_timeline_rtl_spacer() {
+ if (scroll->get_v_scroll_bar()->is_visible() && is_layout_rtl()) {
+ int spacer_width = scroll->get_v_scroll_bar()->get_minimum_size().width;
+ timeline_rtl_spacer->set_custom_minimum_size(Size2(spacer_width, 0));
+ timeline_rtl_spacer->show();
+ } else {
+ timeline_rtl_spacer->hide();
+ }
+}
+
void AnimationTrackEditor::_add_animation_player() {
EditorData &editor_data = EditorNode::get_editor_data();
Node *scene = editor_data.get_edited_scene_root();
@@ -8016,10 +8026,14 @@ void AnimationTrackEditor::popup_read_only_dialog() {
}
AnimationTrackEditor::AnimationTrackEditor() {
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderAnimation");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(mc);
+
main_panel = memnew(PanelContainer);
main_panel->set_focus_mode(FOCUS_ALL); // Allow panel to have focus so that shortcuts work as expected.
- add_child(main_panel);
- main_panel->set_v_size_flags(SIZE_EXPAND_FILL);
+ mc->add_child(main_panel);
HBoxContainer *timeline_scroll = memnew(HBoxContainer);
main_panel->add_child(timeline_scroll);
timeline_scroll->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -8052,8 +8066,13 @@ AnimationTrackEditor::AnimationTrackEditor() {
add_animation_player->set_h_size_flags(SIZE_SHRINK_CENTER);
add_animation_player->connect(SceneStringName(pressed), callable_mp(this, &AnimationTrackEditor::_add_animation_player));
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ hbox->add_theme_constant_override(SNAME("separation"), 0);
+ timeline_vbox->add_child(hbox);
+
timeline = memnew(AnimationTimelineEdit);
- timeline_vbox->add_child(timeline);
+ timeline->set_h_size_flags(SIZE_EXPAND_FILL);
+ hbox->add_child(timeline);
timeline->set_editor(this);
timeline->connect("timeline_changed", callable_mp(this, &AnimationTrackEditor::_timeline_changed));
timeline->connect("name_limit_changed", callable_mp(this, &AnimationTrackEditor::_name_limit_changed));
@@ -8062,6 +8081,11 @@ AnimationTrackEditor::AnimationTrackEditor() {
timeline->connect("length_changed", callable_mp(this, &AnimationTrackEditor::_update_length));
timeline->connect("filter_changed", callable_mp(this, &AnimationTrackEditor::_update_tracks));
+ // If the animation editor is changed to take right-to-left into account, this won't be needed anymore.
+ timeline_rtl_spacer = memnew(Control);
+ timeline_rtl_spacer->hide();
+ hbox->add_child(timeline_rtl_spacer);
+
panner.instantiate();
panner->set_scroll_zoom_factor(AnimationTimelineEdit::SCROLL_ZOOM_FACTOR_IN);
panner->set_callbacks(callable_mp(this, &AnimationTrackEditor::_pan_callback), callable_mp(this, &AnimationTrackEditor::_zoom_callback));
@@ -8090,16 +8114,17 @@ AnimationTrackEditor::AnimationTrackEditor() {
marker_edit->connect(SceneStringName(draw), callable_mp((CanvasItem *)bezier_edit, &CanvasItem::queue_redraw));
scroll = memnew(ScrollContainer);
+ scroll->set_scroll_hint_mode(ScrollContainer::SCROLL_HINT_MODE_ALL);
box_selection_container->add_child(scroll);
scroll->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
- VScrollBar *sb = scroll->get_v_scroll_bar();
- scroll->remove_child(sb);
- timeline_scroll->add_child(sb); // Move here so timeline and tracks are always aligned.
scroll->set_focus_mode(FOCUS_CLICK);
scroll->connect(SceneStringName(gui_input), callable_mp(this, &AnimationTrackEditor::_scroll_input));
scroll->connect(SceneStringName(focus_exited), callable_mp(panner.ptr(), &ViewPanner::release_pan_key));
+ // Must be updated from here, so it guarantees that the scrollbar theme has already changed.
+ scroll->connect(SceneStringName(theme_changed), callable_mp(this, &AnimationTrackEditor::_update_timeline_rtl_spacer), CONNECT_DEFERRED);
+ scroll->get_v_scroll_bar()->connect(SceneStringName(visibility_changed), callable_mp(this, &AnimationTrackEditor::_update_timeline_rtl_spacer));
scroll->get_v_scroll_bar()->connect(SceneStringName(value_changed), callable_mp(this, &AnimationTrackEditor::_v_scroll_changed));
scroll->get_h_scroll_bar()->connect(SceneStringName(value_changed), callable_mp(this, &AnimationTrackEditor::_h_scroll_changed));
diff --git a/editor/animation/animation_track_editor.h b/editor/animation/animation_track_editor.h
index 2dd16b0383f..9af1cdb69fd 100644
--- a/editor/animation/animation_track_editor.h
+++ b/editor/animation/animation_track_editor.h
@@ -617,6 +617,9 @@ class AnimationTrackEditor : public VBoxContainer {
AnimationBezierTrackEdit *bezier_edit = nullptr;
VBoxContainer *timeline_vbox = nullptr;
+ Control *timeline_rtl_spacer = nullptr;
+ void _update_timeline_rtl_spacer();
+
VBoxContainer *info_message_vbox = nullptr;
Label *info_message = nullptr;
Button *add_animation_player = nullptr;
diff --git a/editor/audio/editor_audio_buses.cpp b/editor/audio/editor_audio_buses.cpp
index 68a1e002eb5..3ab45a32680 100644
--- a/editor/audio/editor_audio_buses.cpp
+++ b/editor/audio/editor_audio_buses.cpp
@@ -1387,10 +1387,16 @@ EditorAudioBuses::EditorAudioBuses() {
top_hb->add_child(_new);
_new->connect(SceneStringName(pressed), callable_mp(this, &EditorAudioBuses::_new_layout));
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontal");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_vb->add_child(mc);
+
bus_scroll = memnew(ScrollContainer);
- bus_scroll->set_v_size_flags(SIZE_EXPAND_FILL);
+ bus_scroll->set_scroll_hint_mode(ScrollContainer::SCROLL_HINT_MODE_ALL);
bus_scroll->set_custom_minimum_size(Size2(0, 40 * EDSCALE));
- main_vb->add_child(bus_scroll);
+ mc->add_child(bus_scroll);
+
bus_hb = memnew(HBoxContainer);
bus_hb->set_v_size_flags(SIZE_EXPAND_FILL);
bus_scroll->add_child(bus_hb);
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index c07331dadba..45fc84ad672 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -70,7 +70,6 @@ EditorDebuggerNode::EditorDebuggerNode() {
set_global(false);
set_transient(true);
- set_clip_contents(false);
_update_margins();
if (!singleton) {
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index 60c4e7e5e54..7c4fe707c85 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -2352,14 +2352,12 @@ Instead, use the monitors tab to obtain more precise VRAM usage.
vmem_refresh->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditorDebugger::_video_mem_request));
vmem_export->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditorDebugger::_video_mem_export));
- VBoxContainer *vmmc = memnew(VBoxContainer);
- vmem_tree = memnew(Tree);
- vmem_tree->set_v_size_flags(SIZE_EXPAND_FILL);
- vmem_tree->set_h_size_flags(SIZE_EXPAND_FILL);
- vmmc->add_child(vmem_tree);
- vmmc->set_v_size_flags(SIZE_EXPAND_FILL);
- vmem_vb->add_child(vmmc);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontalWindow");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ vmem_vb->add_child(mc);
+ vmem_tree = memnew(Tree);
vmem_vb->set_name(TTRC("Video RAM"));
vmem_tree->set_columns(4);
vmem_tree->set_column_titles_visible(true);
@@ -2375,6 +2373,8 @@ Instead, use the monitors tab to obtain more precise VRAM usage.
vmem_tree->set_column_title(3, TTRC("Usage"));
vmem_tree->set_column_custom_minimum_width(3, 80 * EDSCALE);
vmem_tree->set_hide_root(true);
+ vmem_tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_TOP);
+ mc->add_child(vmem_tree);
vmem_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_vmem_item_activated));
tabs->add_child(vmem_vb);
diff --git a/editor/doc/editor_help_search.cpp b/editor/doc/editor_help_search.cpp
index ba792a80ebe..f63c9dc6f3e 100644
--- a/editor/doc/editor_help_search.cpp
+++ b/editor/doc/editor_help_search.cpp
@@ -38,6 +38,7 @@
#include "editor/themes/editor_scale.h"
#include "editor/themes/editor_theme_manager.h"
#include "scene/gui/line_edit.h"
+#include "scene/gui/margin_container.h"
bool EditorHelpSearch::_all_terms_in_name(const Vector &p_terms, const String &p_name) const {
for (int i = 0; i < p_terms.size(); i++) {
@@ -373,11 +374,15 @@ EditorHelpSearch::EditorHelpSearch() {
filter_combo->connect(SceneStringName(item_selected), callable_mp(this, &EditorHelpSearch::_filter_combo_item_selected));
hbox->add_child(filter_combo);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontalWindow");
+ mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ vbox->add_child(mc);
+
// Create the results tree.
results_tree = memnew(Tree);
results_tree->set_accessibility_name(TTRC("Search Results"));
results_tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
- results_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
results_tree->set_columns(2);
results_tree->set_column_title(0, TTR("Name"));
results_tree->set_column_clip_content(0, true);
@@ -388,9 +393,10 @@ EditorHelpSearch::EditorHelpSearch() {
results_tree->set_custom_minimum_size(Size2(0, 100) * EDSCALE);
results_tree->set_hide_root(true);
results_tree->set_select_mode(Tree::SELECT_ROW);
+ results_tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_BOTH);
results_tree->connect("item_activated", callable_mp(this, &EditorHelpSearch::_confirmed));
results_tree->connect(SceneStringName(item_selected), callable_mp((BaseButton *)get_ok_button(), &BaseButton::set_disabled).bind(false));
- vbox->add_child(results_tree, true);
+ mc->add_child(results_tree, true);
}
void EditorHelpSearch::TreeCache::clear() {
diff --git a/editor/docks/editor_dock.cpp b/editor/docks/editor_dock.cpp
index 149b768c6bf..10326f93b69 100644
--- a/editor/docks/editor_dock.cpp
+++ b/editor/docks/editor_dock.cpp
@@ -105,7 +105,6 @@ void EditorDock::_bind_methods() {
}
EditorDock::EditorDock() {
- set_clip_contents(true);
add_user_signal(MethodInfo("tab_style_changed"));
}
diff --git a/editor/docks/filesystem_dock.cpp b/editor/docks/filesystem_dock.cpp
index f3b9fa88568..f6392ac909b 100644
--- a/editor/docks/filesystem_dock.cpp
+++ b/editor/docks/filesystem_dock.cpp
@@ -484,10 +484,13 @@ void FileSystemDock::_update_display_mode(bool p_force) {
// Compute the new display mode.
if (p_force || old_display_mode != display_mode) {
switch (display_mode) {
- case DISPLAY_MODE_TREE_ONLY:
+ case DISPLAY_MODE_TREE_ONLY: {
button_toggle_display_mode->set_button_icon(get_editor_theme_icon(SNAME("Panels1")));
tree->show();
tree->set_v_size_flags(SIZE_EXPAND_FILL);
+ tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_TOP);
+ tree->set_theme_type_variation("");
+ tree_mc->set_theme_type_variation("NoBorderHorizontalBottom");
if (horizontal) {
toolbar2_hbc->hide();
} else {
@@ -497,10 +500,10 @@ void FileSystemDock::_update_display_mode(bool p_force) {
_update_tree(get_uncollapsed_paths());
file_list_vb->hide();
- break;
+ } break;
case DISPLAY_MODE_HSPLIT:
- case DISPLAY_MODE_VSPLIT:
+ case DISPLAY_MODE_VSPLIT: {
const bool is_vertical = display_mode == DISPLAY_MODE_VSPLIT;
split_box->set_vertical(is_vertical);
@@ -511,15 +514,26 @@ void FileSystemDock::_update_display_mode(bool p_force) {
tree->show();
tree->set_v_size_flags(SIZE_EXPAND_FILL);
+ if (is_vertical) {
+ tree->set_theme_type_variation("");
+ tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_BOTH);
+ tree_mc->set_theme_type_variation("NoBorderHorizontal");
+ } else {
+ tree->set_theme_type_variation("TreeSecondary");
+ tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_DISABLED);
+ tree_mc->set_theme_type_variation("");
+ }
tree->ensure_cursor_is_visible();
+
toolbar2_hbc->hide();
button_file_list_display_mode->show();
_update_tree(get_uncollapsed_paths());
file_list_vb->show();
_update_file_list(true);
- break;
+ } break;
}
+
old_display_mode = display_mode;
}
}
@@ -4322,18 +4336,22 @@ FileSystemDock::FileSystemDock() {
split_box_offset_h = 240 * EDSCALE;
main_vb->add_child(split_box);
+ tree_mc = memnew(MarginContainer);
+ split_box->add_child(tree_mc);
+ tree_mc->set_theme_type_variation("NoBorderHorizontalBottom");
+ tree_mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+
tree = memnew(FileSystemTree);
tree->set_accessibility_name(TTRC("Directories"));
- tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
-
tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
tree->set_hide_root(true);
+ tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_TOP);
SET_DRAG_FORWARDING_GCD(tree, FileSystemDock);
tree->set_allow_rmb_select(true);
tree->set_select_mode(Tree::SELECT_MULTI);
tree->set_custom_minimum_size(Size2(40 * EDSCALE, 15 * EDSCALE));
tree->set_column_clip_content(0, true);
- split_box->add_child(tree);
+ tree_mc->add_child(tree);
tree->connect("item_activated", callable_mp(this, &FileSystemDock::_tree_activate_file));
tree->connect("multi_selected", callable_mp(this, &FileSystemDock::_tree_multi_selected));
diff --git a/editor/docks/filesystem_dock.h b/editor/docks/filesystem_dock.h
index ad0dcb99bb1..1af4867fe0f 100644
--- a/editor/docks/filesystem_dock.h
+++ b/editor/docks/filesystem_dock.h
@@ -153,6 +153,7 @@ private:
VBoxContainer *scanning_vb = nullptr;
ProgressBar *scanning_progress = nullptr;
SplitContainer *split_box = nullptr;
+ MarginContainer *tree_mc = nullptr;
VBoxContainer *file_list_vb = nullptr;
int split_box_offset_h = 0;
diff --git a/editor/docks/groups_dock.cpp b/editor/docks/groups_dock.cpp
index d82e5be7cf9..6faf105a11a 100644
--- a/editor/docks/groups_dock.cpp
+++ b/editor/docks/groups_dock.cpp
@@ -31,7 +31,6 @@
#include "groups_dock.h"
#include "editor/settings/editor_command_palette.h"
-#include "editor/themes/editor_scale.h"
void GroupsDock::set_selection(const Vector &p_nodes) {
groups->set_selection(p_nodes);
@@ -44,12 +43,9 @@ GroupsDock::GroupsDock() {
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_groups", TTRC("Open Groups Dock")));
set_default_slot(DockConstants::DOCK_SLOT_RIGHT_UL);
- VBoxContainer *main_vb = memnew(VBoxContainer);
- add_child(main_vb);
-
groups = memnew(GroupsEditor);
- main_vb->add_child(groups);
groups->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(groups);
}
GroupsDock::~GroupsDock() {
diff --git a/editor/docks/groups_editor.cpp b/editor/docks/groups_editor.cpp
index d412c114b38..6a26f5f592d 100644
--- a/editor/docks/groups_editor.cpp
+++ b/editor/docks/groups_editor.cpp
@@ -911,16 +911,21 @@ GroupsEditor::GroupsEditor() {
filter->connect(SceneStringName(text_changed), callable_mp(this, &GroupsEditor::_update_tree).unbind(1));
hbc->add_child(filter);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontalBottom");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ holder->add_child(mc);
+
tree = memnew(Tree);
tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
tree->set_hide_root(true);
- tree->set_v_size_flags(SIZE_EXPAND_FILL);
tree->set_allow_rmb_select(true);
tree->set_select_mode(Tree::SelectMode::SELECT_SINGLE);
+ tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_TOP);
+ mc->add_child(tree);
tree->connect("button_clicked", callable_mp(this, &GroupsEditor::_modify_group));
tree->connect("item_mouse_selected", callable_mp(this, &GroupsEditor::_item_mouse_selected));
tree->connect(SceneStringName(gui_input), callable_mp(this, &GroupsEditor::_groups_gui_input));
- holder->add_child(tree);
menu = memnew(PopupMenu);
menu->connect(SceneStringName(id_pressed), callable_mp(this, &GroupsEditor::_menu_id_pressed));
diff --git a/editor/docks/history_dock.cpp b/editor/docks/history_dock.cpp
index 37eb006ac27..0a8b6fa7854 100644
--- a/editor/docks/history_dock.cpp
+++ b/editor/docks/history_dock.cpp
@@ -269,9 +269,15 @@ HistoryDock::HistoryDock() {
global_history_checkbox->set_pressed(true);
global_history_checkbox->connect(SceneStringName(toggled), callable_mp(this, &HistoryDock::refresh_history).unbind(1));
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontalBottom");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_vb->add_child(mc);
+
action_list = memnew(ItemList);
+ action_list->set_scroll_hint_mode(ItemList::SCROLL_HINT_MODE_TOP);
action_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
- main_vb->add_child(action_list);
+ mc->add_child(action_list);
action_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
action_list->connect(SceneStringName(item_selected), callable_mp(this, &HistoryDock::seek_history));
}
diff --git a/editor/docks/import_dock.cpp b/editor/docks/import_dock.cpp
index 8b3bf1612be..89728cc3734 100644
--- a/editor/docks/import_dock.cpp
+++ b/editor/docks/import_dock.cpp
@@ -779,9 +779,14 @@ ImportDock::ImportDock() {
preset->get_popup()->connect("index_pressed", callable_mp(this, &ImportDock::_preset_selected));
hb->add_child(preset);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontal");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ content->add_child(mc);
+
import_opts = memnew(EditorInspector);
- content->add_child(import_opts);
- import_opts->set_v_size_flags(SIZE_EXPAND_FILL);
+ mc->add_child(import_opts);
+ import_opts->set_scroll_hint_mode(ScrollContainer::SCROLL_HINT_MODE_ALL);
import_opts->connect("property_edited", callable_mp(this, &ImportDock::_property_edited));
import_opts->connect("property_toggled", callable_mp(this, &ImportDock::_property_toggled));
// Make it possible to display tooltips stored in the XML class reference.
diff --git a/editor/docks/inspector_dock.cpp b/editor/docks/inspector_dock.cpp
index 4f99d64e99d..ce71305bee9 100644
--- a/editor/docks/inspector_dock.cpp
+++ b/editor/docks/inspector_dock.cpp
@@ -871,11 +871,15 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) {
load_resource_dialog->set_current_dir("res://");
load_resource_dialog->connect("file_selected", callable_mp(this, &InspectorDock::_resource_file_selected));
+ MarginContainer *mc = memnew(MarginContainer);
+ main_vb->add_child(mc);
+ mc->set_theme_type_variation("NoBorderHorizontalBottom");
+ mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+
inspector = memnew(EditorInspector);
- main_vb->add_child(inspector);
+ mc->add_child(inspector);
inspector->set_autoclear(true);
inspector->set_show_categories(true, true);
- inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL);
inspector->set_use_doc_hints(true);
inspector->set_hide_script(false);
inspector->set_hide_metadata(false);
@@ -883,6 +887,7 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) {
inspector->set_property_name_style(property_name_style);
inspector->set_use_folding(!bool(EDITOR_GET("interface/inspector/disable_folding")));
inspector->register_text_enter(search);
+ inspector->set_scroll_hint_mode(ScrollContainer::SCROLL_HINT_MODE_TOP_AND_LEFT);
inspector->set_use_filter(true);
diff --git a/editor/docks/scene_tree_dock.cpp b/editor/docks/scene_tree_dock.cpp
index 3963e009489..17b4bf4a999 100644
--- a/editor/docks/scene_tree_dock.cpp
+++ b/editor/docks/scene_tree_dock.cpp
@@ -4421,10 +4421,11 @@ List SceneTreeDock::get_node_clipboard() const {
return node_clipboard;
}
-void SceneTreeDock::add_remote_tree_editor(Control *p_remote) {
+void SceneTreeDock::add_remote_tree_editor(Tree *p_remote) {
ERR_FAIL_COND(remote_tree != nullptr);
- main_vbox->add_child(p_remote);
+ main_mc->add_child(p_remote);
remote_tree = p_remote;
+ remote_tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_TOP);
remote_tree->hide();
remote_tree->connect("open", callable_mp(this, &SceneTreeDock::_load_request));
}
@@ -4744,7 +4745,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
editor_selection = p_editor_selection;
scene_root = p_scene_root;
- main_vbox = memnew(VBoxContainer);
+ VBoxContainer *main_vbox = memnew(VBoxContainer);
add_child(main_vbox);
HBoxContainer *filter_hbc = memnew(HBoxContainer);
@@ -4872,10 +4873,14 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
create_root_dialog->set_v_size_flags(SIZE_EXPAND_FILL);
create_root_dialog->hide();
- scene_tree = memnew(SceneTreeEditor(false, true, true));
+ main_mc = memnew(MarginContainer);
+ main_vbox->add_child(main_mc);
+ main_mc->set_theme_type_variation("NoBorderHorizontalBottom");
+ main_mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- main_vbox->add_child(scene_tree);
- scene_tree->set_v_size_flags(SIZE_EXPAND | SIZE_FILL);
+ scene_tree = memnew(SceneTreeEditor(false, true, true));
+ main_mc->add_child(scene_tree);
+ scene_tree->get_scene_tree()->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_TOP);
scene_tree->connect("rmb_pressed", callable_mp(this, &SceneTreeDock::_tree_rmb));
scene_tree->connect("node_selected", callable_mp(this, &SceneTreeDock::_node_selected), CONNECT_DEFERRED);
diff --git a/editor/docks/scene_tree_dock.h b/editor/docks/scene_tree_dock.h
index fb5d5256943..36832b95dca 100644
--- a/editor/docks/scene_tree_dock.h
+++ b/editor/docks/scene_tree_dock.h
@@ -103,7 +103,7 @@ class SceneTreeDock : public EditorDock {
int current_option = 0;
- VBoxContainer *main_vbox = nullptr;
+ MarginContainer *main_mc = nullptr;
CreateDialog *create_dialog = nullptr;
RenameDialog *rename_dialog = nullptr;
@@ -128,7 +128,7 @@ class SceneTreeDock : public EditorDock {
HBoxContainer *button_hb = nullptr;
Button *edit_local, *edit_remote;
SceneTreeEditor *scene_tree = nullptr;
- Control *remote_tree = nullptr;
+ Tree *remote_tree = nullptr;
void _tool_selected(int p_tool, bool p_confirm_override = false);
void _property_selected(int p_idx);
@@ -336,7 +336,7 @@ public:
SceneTreeEditor *get_tree_editor() { return scene_tree; }
EditorData *get_editor_data() { return editor_data; }
- void add_remote_tree_editor(Control *p_remote);
+ void add_remote_tree_editor(Tree *p_remote);
void show_remote_tree();
void hide_remote_tree();
void show_tab_buttons();
diff --git a/editor/docks/signals_dock.cpp b/editor/docks/signals_dock.cpp
index 28fb078f9f2..e7ae0e566c9 100644
--- a/editor/docks/signals_dock.cpp
+++ b/editor/docks/signals_dock.cpp
@@ -32,7 +32,6 @@
#include "editor/scene/connections_dialog.h"
#include "editor/settings/editor_command_palette.h"
-#include "editor/themes/editor_scale.h"
void SignalsDock::update_lists() {
connections->update_tree();
@@ -49,12 +48,9 @@ SignalsDock::SignalsDock() {
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_signals", TTRC("Open Signals Dock")));
set_default_slot(DockConstants::DOCK_SLOT_RIGHT_UL);
- VBoxContainer *main_vb = memnew(VBoxContainer);
- add_child(main_vb);
-
connections = memnew(ConnectionsDock);
- main_vb->add_child(connections);
connections->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(connections);
}
SignalsDock::~SignalsDock() {
diff --git a/editor/import/import_defaults_editor.cpp b/editor/import/import_defaults_editor.cpp
index d9422744c8a..2cebe0c9823 100644
--- a/editor/import/import_defaults_editor.cpp
+++ b/editor/import/import_defaults_editor.cpp
@@ -37,6 +37,7 @@
#include "editor/settings/action_map_editor.h"
#include "scene/gui/center_container.h"
#include "scene/gui/label.h"
+#include "scene/gui/margin_container.h"
class ImportDefaultsEditorSettings : public Object {
GDCLASS(ImportDefaultsEditorSettings, Object)
@@ -213,12 +214,17 @@ ImportDefaultsEditor::ImportDefaultsEditor() {
hb->add_child(reset_defaults);
add_child(hb);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontal");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(mc);
+
inspector = memnew(EditorInspector);
- add_child(inspector);
- inspector->set_v_size_flags(SIZE_EXPAND_FILL);
+ inspector->set_scroll_hint_mode(ScrollContainer::SCROLL_HINT_MODE_ALL);
// Make it possible to display tooltips stored in the XML class reference.
// The object name is set when the importer changes in `_update_importer()`.
inspector->set_use_doc_hints(true);
+ mc->add_child(inspector);
CenterContainer *cc = memnew(CenterContainer);
save_defaults = memnew(Button);
diff --git a/editor/scene/connections_dialog.cpp b/editor/scene/connections_dialog.cpp
index a4e6272c4b1..60e5a6791de 100644
--- a/editor/scene/connections_dialog.cpp
+++ b/editor/scene/connections_dialog.cpp
@@ -1719,16 +1719,21 @@ ConnectionsDock::ConnectionsDock() {
search_box->connect(SceneStringName(text_changed), callable_mp(this, &ConnectionsDock::_filter_changed));
holder->add_child(search_box);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontal");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ holder->add_child(mc);
+
tree = memnew(ConnectionsDockTree);
tree->set_accessibility_name(TTRC("Connections"));
tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
tree->set_columns(1);
tree->set_select_mode(Tree::SELECT_ROW);
tree->set_hide_root(true);
- tree->set_column_clip_content(0, true);
- holder->add_child(tree);
- tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tree->set_allow_rmb_select(true);
+ tree->set_column_clip_content(0, true);
+ tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_BOTH);
+ mc->add_child(tree);
connect_button = memnew(Button);
connect_button->set_accessibility_name(TTRC("Connect"));
diff --git a/editor/scene/resource_preloader_editor_plugin.cpp b/editor/scene/resource_preloader_editor_plugin.cpp
index 97a51092c88..5a905e9f0ea 100644
--- a/editor/scene/resource_preloader_editor_plugin.cpp
+++ b/editor/scene/resource_preloader_editor_plugin.cpp
@@ -339,6 +339,22 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant
}
}
+void ResourcePreloaderEditor::update_layout(EditorDock::DockLayout p_layout) {
+ bool new_horizontal = (p_layout == EditorDock::DOCK_LAYOUT_HORIZONTAL);
+ if (horizontal == new_horizontal) {
+ return;
+ }
+ horizontal = new_horizontal;
+
+ if (horizontal) {
+ mc->set_theme_type_variation("NoBorderHorizontal");
+ tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_BOTH);
+ } else {
+ mc->set_theme_type_variation("NoBorderHorizontalBottom");
+ tree->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_TOP);
+ }
+}
+
void ResourcePreloaderEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_library"), &ResourcePreloaderEditor::_update_library);
ClassDB::bind_method(D_METHOD("_remove_resource", "to_remove"), &ResourcePreloaderEditor::_remove_resource);
@@ -372,6 +388,10 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
file = memnew(EditorFileDialog);
add_child(file);
+ mc = memnew(MarginContainer);
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ vbc->add_child(mc);
+
tree = memnew(Tree);
tree->connect("button_clicked", callable_mp(this, &ResourcePreloaderEditor::_cell_button_pressed));
tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
@@ -381,10 +401,9 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
tree->set_column_clip_content(0, true);
tree->set_column_expand_ratio(1, 3);
tree->set_column_clip_content(1, true);
- tree->set_v_size_flags(SIZE_EXPAND_FILL);
SET_DRAG_FORWARDING_GCD(tree, ResourcePreloaderEditor);
- vbc->add_child(tree);
+ mc->add_child(tree);
dialog = memnew(AcceptDialog);
dialog->set_title(TTRC("Error!"));
diff --git a/editor/scene/resource_preloader_editor_plugin.h b/editor/scene/resource_preloader_editor_plugin.h
index 5db79e8c9a2..a6fe3694115 100644
--- a/editor/scene/resource_preloader_editor_plugin.h
+++ b/editor/scene/resource_preloader_editor_plugin.h
@@ -50,8 +50,11 @@ class ResourcePreloaderEditor : public EditorDock {
Button *load = nullptr;
Button *paste = nullptr;
+ MarginContainer *mc = nullptr;
Tree *tree = nullptr;
- bool loading_scene;
+
+ bool horizontal = false;
+ bool loading_scene = false;
EditorFileDialog *file = nullptr;
@@ -73,9 +76,10 @@ class ResourcePreloaderEditor : public EditorDock {
protected:
void _notification(int p_what);
-
static void _bind_methods();
+ virtual void update_layout(EditorDock::DockLayout p_layout) override;
+
public:
void edit(ResourcePreloader *p_preloader);
ResourcePreloaderEditor();
diff --git a/editor/script/find_in_files.cpp b/editor/script/find_in_files.cpp
index 21708e3f1c4..334d1eef03f 100644
--- a/editor/script/find_in_files.cpp
+++ b/editor/script/find_in_files.cpp
@@ -1307,7 +1307,6 @@ FindInFilesContainer::FindInFilesContainer() {
set_transient(true);
set_closable(true);
set_custom_minimum_size(Size2(0, 200 * EDSCALE));
- set_clip_contents(false);
_tabs = memnew(TabContainer);
_tabs->set_tabs_visible(false);
diff --git a/editor/settings/editor_command_palette.cpp b/editor/settings/editor_command_palette.cpp
index ad70973e107..3c06b0ad533 100644
--- a/editor/settings/editor_command_palette.cpp
+++ b/editor/settings/editor_command_palette.cpp
@@ -356,6 +356,12 @@ EditorCommandPalette::EditorCommandPalette() {
vbc->add_child(margin_container_csb);
register_text_enter(command_search_box);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontalWindow");
+ mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ mc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ vbc->add_child(mc);
+
search_options = memnew(Tree);
search_options->connect("item_activated", callable_mp(this, &EditorCommandPalette::_confirmed));
search_options->connect(SceneStringName(item_selected), callable_mp((BaseButton *)get_ok_button(), &BaseButton::set_disabled).bind(false));
@@ -363,10 +369,9 @@ EditorCommandPalette::EditorCommandPalette() {
search_options->create_item();
search_options->set_hide_root(true);
search_options->set_columns(2);
- search_options->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- search_options->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search_options->set_column_custom_minimum_width(0, int(8 * EDSCALE));
- vbc->add_child(search_options, true);
+ search_options->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_BOTH);
+ mc->add_child(search_options, true);
}
Ref ED_SHORTCUT_AND_COMMAND(const String &p_path, const String &p_name, Key p_keycode, String p_command_name) {
diff --git a/editor/shader/shader_globals_editor.cpp b/editor/shader/shader_globals_editor.cpp
index c8c96ace501..73266d4e0ae 100644
--- a/editor/shader/shader_globals_editor.cpp
+++ b/editor/shader/shader_globals_editor.cpp
@@ -36,6 +36,7 @@
#include "editor/inspector/editor_inspector.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
+#include "scene/gui/margin_container.h"
#include "servers/rendering/shader_language.h"
static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = {
@@ -487,12 +488,17 @@ ShaderGlobalsEditor::ShaderGlobalsEditor() {
add_menu_hb->add_child(variable_add);
variable_add->connect(SceneStringName(pressed), callable_mp(this, &ShaderGlobalsEditor::_variable_added));
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontalBottom");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ add_child(mc);
+
inspector = memnew(EditorInspector);
- inspector->set_v_size_flags(SIZE_EXPAND_FILL);
- add_child(inspector);
inspector->set_use_wide_editors(true);
inspector->set_property_name_style(EditorPropertyNameProcessor::STYLE_RAW);
inspector->set_use_deletable_properties(true);
+ inspector->set_scroll_hint_mode(ScrollContainer::SCROLL_HINT_MODE_TOP_AND_LEFT);
+ mc->add_child(inspector);
inspector->connect("property_deleted", callable_mp(this, &ShaderGlobalsEditor::_variable_deleted), CONNECT_DEFERRED);
interface = memnew(ShaderGlobalsEditorInterface);
diff --git a/editor/themes/theme_classic.cpp b/editor/themes/theme_classic.cpp
index e570bfc5a6c..4a6ffa6acc4 100644
--- a/editor/themes/theme_classic.cpp
+++ b/editor/themes/theme_classic.cpp
@@ -1588,6 +1588,7 @@ void ThemeClassic::populate_editor_styles(const Ref &p_theme, Edito
p_theme->set_icon("scroll_hint_vertical", "ScrollContainer", empty_texture);
p_theme->set_icon("scroll_hint_horizontal", "ScrollContainer", empty_texture);
p_theme->set_icon("scroll_hint", "Tree", empty_texture);
+ p_theme->set_icon("scroll_hint", "ItemList", empty_texture);
// This stylebox is used in 3d and 2d viewports (no borders).
Ref style_content_panel_vp = p_config.content_panel_style->duplicate();
diff --git a/editor/themes/theme_modern.cpp b/editor/themes/theme_modern.cpp
index 11e698685ac..312ddd940bb 100644
--- a/editor/themes/theme_modern.cpp
+++ b/editor/themes/theme_modern.cpp
@@ -1861,6 +1861,33 @@ void ThemeModern::populate_editor_styles(const Ref &p_theme, Editor
p_theme->set_stylebox(SceneStringName(panel), "EditorAbout", p_config.window_complex_style);
p_theme->set_stylebox(SceneStringName(panel), "ThemeItemEditorDialog", p_config.window_complex_style);
+ // MarginContainers with negative margins, to negate borders. Used with scroll hints.
+ {
+ int margin = -p_theme->get_stylebox(SceneStringName(panel), SNAME("PanelContainer"))->get_content_margin(SIDE_LEFT);
+
+ p_theme->set_type_variation("NoBorderHorizontal", "MarginContainer");
+ p_theme->set_constant("margin_left", "NoBorderHorizontal", margin);
+ p_theme->set_constant("margin_right", "NoBorderHorizontal", margin);
+
+ p_theme->set_type_variation("NoBorderHorizontalBottom", "MarginContainer");
+ p_theme->set_constant("margin_left", "NoBorderHorizontalBottom", margin);
+ p_theme->set_constant("margin_right", "NoBorderHorizontalBottom", margin);
+ p_theme->set_constant("margin_bottom", "NoBorderHorizontalBottom", margin);
+
+ margin = margin - p_theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))->get_content_margin(SIDE_LEFT);
+
+ // Used in the animation track editor.
+ p_theme->set_type_variation("NoBorderAnimation", "MarginContainer");
+ p_theme->set_constant("margin_left", "NoBorderAnimation", margin);
+ p_theme->set_constant("margin_right", "NoBorderAnimation", margin);
+
+ margin = -p_theme->get_stylebox(SceneStringName(panel), SNAME("AcceptDialog"))->get_content_margin(SIDE_LEFT);
+
+ p_theme->set_type_variation("NoBorderHorizontalWindow", "MarginContainer");
+ p_theme->set_constant("margin_left", "NoBorderHorizontalWindow", margin);
+ p_theme->set_constant("margin_right", "NoBorderHorizontalWindow", margin);
+ }
+
// Buttons in material previews.
{
const Color dim_light_color = p_config.icon_normal_color.darkened(0.24);
diff --git a/editor/translations/localization_editor.cpp b/editor/translations/localization_editor.cpp
index 4785eeacf19..9a6d8850d33 100644
--- a/editor/translations/localization_editor.cpp
+++ b/editor/translations/localization_editor.cpp
@@ -751,13 +751,14 @@ LocalizationEditor::LocalizationEditor() {
addtr->connect(SceneStringName(pressed), callable_mp(this, &LocalizationEditor::_translation_file_open));
thb->add_child(addtr);
- VBoxContainer *tmc = memnew(VBoxContainer);
- tmc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- tvb->add_child(tmc);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontalBottom");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ tvb->add_child(mc);
translation_list = memnew(Tree);
- translation_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- tmc->add_child(translation_list);
+ translation_list->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_TOP);
+ mc->add_child(translation_list);
trees.push_back(translation_list);
tree_data_types[translation_list] = "localization_editor_translation_item";
tree_settings[translation_list] = "internationalization/locale/translations";
@@ -788,15 +789,16 @@ LocalizationEditor::LocalizationEditor() {
addtr->connect(SceneStringName(pressed), callable_mp(this, &LocalizationEditor::_translation_res_file_open));
thb->add_child(addtr);
- VBoxContainer *tmc = memnew(VBoxContainer);
- tmc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- tvb->add_child(tmc);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontal");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ tvb->add_child(mc);
translation_remap = memnew(Tree);
- translation_remap->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ translation_remap->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_BOTH);
translation_remap->connect("cell_selected", callable_mp(this, &LocalizationEditor::_translation_res_select));
translation_remap->connect("button_clicked", callable_mp(this, &LocalizationEditor::_translation_res_delete));
- tmc->add_child(translation_remap);
+ mc->add_child(translation_remap);
translation_res_file_open_dialog = memnew(EditorFileDialog);
translation_res_file_open_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
@@ -815,10 +817,6 @@ LocalizationEditor::LocalizationEditor() {
translation_res_option_add_button = addtr;
thb->add_child(addtr);
- tmc = memnew(VBoxContainer);
- tmc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- tvb->add_child(tmc);
-
translation_remap_options = memnew(Tree);
translation_remap_options->set_v_size_flags(Control::SIZE_EXPAND_FILL);
translation_remap_options->set_columns(2);
@@ -833,7 +831,7 @@ LocalizationEditor::LocalizationEditor() {
translation_remap_options->connect("item_edited", callable_mp(this, &LocalizationEditor::_translation_res_option_changed));
translation_remap_options->connect("button_clicked", callable_mp(this, &LocalizationEditor::_translation_res_option_delete));
translation_remap_options->connect("custom_popup_edited", callable_mp(this, &LocalizationEditor::_translation_res_option_popup));
- tmc->add_child(translation_remap_options);
+ mc->add_child(translation_remap_options);
translation_res_option_file_open_dialog = memnew(EditorFileDialog);
translation_res_option_file_open_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
@@ -861,9 +859,14 @@ LocalizationEditor::LocalizationEditor() {
template_generate_button->connect(SceneStringName(pressed), callable_mp(this, &LocalizationEditor::_template_generate_open));
thb->add_child(template_generate_button);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->set_theme_type_variation("NoBorderHorizontal");
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ tvb->add_child(mc);
+
template_source_list = memnew(Tree);
- template_source_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- tvb->add_child(template_source_list);
+ template_source_list->set_scroll_hint_mode(Tree::SCROLL_HINT_MODE_BOTH);
+ mc->add_child(template_source_list);
trees.push_back(template_source_list);
tree_data_types[template_source_list] = "localization_editor_pot_item";
tree_settings[template_source_list] = "internationalization/locale/translations_pot_files";
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
index 9421ee73559..854cdde6063 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
@@ -208,7 +208,6 @@ namespace GodotTools.Build
AvailableLayouts = DockLayout.Horizontal | DockLayout.Floating;
Global = false;
Transient = true;
- ClipContents = false;
}
public override void _Ready()
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 6f2ebd71fd1..ba114225a23 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -1705,6 +1705,21 @@ void ItemList::_notification(int p_what) {
draw_style_box(cursor, cursor_rcache);
}
+ if (scroll_hint_mode != SCROLL_HINT_MODE_DISABLED) {
+ Size2 control_size = get_size();
+ float v_scroll_value = scroll_bar_v->get_value();
+ bool v_scroll_below_max = v_scroll_value < (scroll_bar_v->get_max() - scroll_bar_v->get_page() - 1);
+ if (v_scroll_value > 1 || v_scroll_below_max) {
+ int hint_height = theme_cache.scroll_hint->get_height();
+ if ((scroll_hint_mode == SCROLL_HINT_MODE_BOTH || scroll_hint_mode == SCROLL_HINT_MODE_TOP) && v_scroll_value > 1) {
+ draw_texture_rect(theme_cache.scroll_hint, Rect2(Point2(), Size2(control_size.width, hint_height)), tile_scroll_hint);
+ }
+ if ((scroll_hint_mode == SCROLL_HINT_MODE_BOTH || scroll_hint_mode == SCROLL_HINT_MODE_BOTTOM) && v_scroll_below_max) {
+ draw_texture_rect(theme_cache.scroll_hint, Rect2(Point2(0, control_size.height - hint_height), Size2(control_size.width, -hint_height)), tile_scroll_hint);
+ }
+ }
+ }
+
if (has_focus(true)) {
RenderingServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(), true);
size.x -= (scroll_bar_h->get_max() - scroll_bar_h->get_page());
@@ -2193,6 +2208,32 @@ bool ItemList::has_wraparound_items() const {
return wraparound_items;
}
+void ItemList::set_scroll_hint_mode(ScrollHintMode p_mode) {
+ if (scroll_hint_mode == p_mode) {
+ return;
+ }
+
+ scroll_hint_mode = p_mode;
+ queue_redraw();
+}
+
+ItemList::ScrollHintMode ItemList::get_scroll_hint_mode() const {
+ return scroll_hint_mode;
+}
+
+void ItemList::set_tile_scroll_hint(bool p_enable) {
+ if (tile_scroll_hint == p_enable) {
+ return;
+ }
+
+ tile_scroll_hint = p_enable;
+ queue_redraw();
+}
+
+bool ItemList::is_scroll_hint_tiled() {
+ return tile_scroll_hint;
+}
+
bool ItemList::_set(const StringName &p_name, const Variant &p_value) {
if (property_helper.property_set_value(p_name, p_value)) {
return true;
@@ -2334,6 +2375,12 @@ void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_v_scroll_bar"), &ItemList::get_v_scroll_bar);
ClassDB::bind_method(D_METHOD("get_h_scroll_bar"), &ItemList::get_h_scroll_bar);
+ ClassDB::bind_method(D_METHOD("set_scroll_hint_mode", "scroll_hint_mode"), &ItemList::set_scroll_hint_mode);
+ ClassDB::bind_method(D_METHOD("get_scroll_hint_mode"), &ItemList::get_scroll_hint_mode);
+
+ ClassDB::bind_method(D_METHOD("set_tile_scroll_hint", "tile_scroll_hint"), &ItemList::set_tile_scroll_hint);
+ ClassDB::bind_method(D_METHOD("is_scroll_hint_tiled"), &ItemList::is_scroll_hint_tiled);
+
ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &ItemList::set_text_overrun_behavior);
ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &ItemList::get_text_overrun_behavior);
@@ -2351,6 +2398,8 @@ void ItemList::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis (6+ Characters),Word Ellipsis (6+ Characters),Ellipsis (Always),Word Ellipsis (Always)"), "set_text_overrun_behavior", "get_text_overrun_behavior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wraparound_items"), "set_wraparound_items", "has_wraparound_items");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_hint_mode", PROPERTY_HINT_ENUM, "Disabled,Both,Top,Bottom"), "set_scroll_hint_mode", "get_scroll_hint_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tile_scroll_hint"), "set_tile_scroll_hint", "is_scroll_hint_tiled");
ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_");
ADD_GROUP("Columns", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_columns", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), "set_max_columns", "get_max_columns");
@@ -2368,6 +2417,11 @@ void ItemList::_bind_methods() {
BIND_ENUM_CONSTANT(SELECT_MULTI);
BIND_ENUM_CONSTANT(SELECT_TOGGLE);
+ BIND_ENUM_CONSTANT(SCROLL_HINT_MODE_DISABLED);
+ BIND_ENUM_CONSTANT(SCROLL_HINT_MODE_BOTH);
+ BIND_ENUM_CONSTANT(SCROLL_HINT_MODE_TOP);
+ BIND_ENUM_CONSTANT(SCROLL_HINT_MODE_BOTTOM);
+
ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "index")));
ADD_SIGNAL(MethodInfo("empty_clicked", PropertyInfo(Variant::VECTOR2, "at_position"), PropertyInfo(Variant::INT, "mouse_button_index")));
ADD_SIGNAL(MethodInfo("item_clicked", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::VECTOR2, "at_position"), PropertyInfo(Variant::INT, "mouse_button_index")));
@@ -2388,6 +2442,7 @@ void ItemList::_bind_methods() {
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_selected_color);
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_CONSTANT, ItemList, font_outline_size, "outline_size");
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_outline_color);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ItemList, scroll_hint);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ItemList, line_separation);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ItemList, icon_margin);
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index 05410df88fe..2a06e5c306f 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -50,6 +50,13 @@ public:
SELECT_TOGGLE,
};
+ enum ScrollHintMode {
+ SCROLL_HINT_MODE_DISABLED,
+ SCROLL_HINT_MODE_BOTH,
+ SCROLL_HINT_MODE_TOP,
+ SCROLL_HINT_MODE_BOTTOM,
+ };
+
private:
struct Item {
mutable RID accessibility_item_element;
@@ -123,6 +130,9 @@ private:
HScrollBar *scroll_bar_h = nullptr;
TextServer::OverrunBehavior text_overrun_behavior = TextServer::OVERRUN_TRIM_ELLIPSIS;
+ ScrollHintMode scroll_hint_mode = SCROLL_HINT_MODE_DISABLED;
+ bool tile_scroll_hint = false;
+
uint64_t search_time_msec = 0;
String search_string;
@@ -176,6 +186,8 @@ protected:
Ref cursor_style;
Ref cursor_focus_style;
Color guide_color;
+
+ Ref scroll_hint;
} theme_cache;
void _notification(int p_what);
@@ -335,9 +347,16 @@ public:
VScrollBar *get_v_scroll_bar() { return scroll_bar_v; }
HScrollBar *get_h_scroll_bar() { return scroll_bar_h; }
+ void set_scroll_hint_mode(ScrollHintMode p_mode);
+ ScrollHintMode get_scroll_hint_mode() const;
+
+ void set_tile_scroll_hint(bool p_enable);
+ bool is_scroll_hint_tiled();
+
ItemList();
~ItemList();
};
VARIANT_ENUM_CAST(ItemList::SelectMode);
VARIANT_ENUM_CAST(ItemList::IconMode);
+VARIANT_ENUM_CAST(ItemList::ScrollHintMode);
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 0f153c96b4d..b7f20be2190 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -43,16 +43,11 @@ Size2 ScrollContainer::get_minimum_size() const {
for (int i = 0; i < get_child_count(); i++) {
Control *c = as_sortable_control(get_child(i), SortableVisibilityMode::VISIBLE);
- if (!c) {
- continue;
- }
- // Ignore the scroll hints.
- if (c == h_scroll || c == v_scroll || c == focus_panel) {
+ if (!c || c == h_scroll || c == v_scroll || c == focus_panel || c == scroll_hint_top_left || c == scroll_hint_bottom_right) {
continue;
}
Size2 child_min_size = c->get_combined_minimum_size();
-
largest_child_min_size = largest_child_min_size.max(child_min_size);
}
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index e47c6753801..5e2260169c2 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -4556,6 +4556,7 @@ void Tree::update_scrollbars() {
theme_cache.offset.y = v_scroll->get_value();
} else {
v_scroll->hide();
+ v_scroll->set_value(0);
theme_cache.offset.y = 0;
}
@@ -4566,6 +4567,7 @@ void Tree::update_scrollbars() {
theme_cache.offset.x = h_scroll->get_value();
} else {
h_scroll->hide();
+ h_scroll->set_value(0);
theme_cache.offset.x = 0;
}
@@ -5131,7 +5133,7 @@ void Tree::_notification(int p_what) {
if (scroll_hint_mode != SCROLL_HINT_MODE_DISABLED) {
Size2 size = get_size();
float v_scroll_value = v_scroll->get_value();
- bool v_scroll_below_max = v_scroll_value < (get_internal_min_size().height - size.height - 1);
+ bool v_scroll_below_max = v_scroll_value < (get_internal_min_size().height - (content_rect.get_size().height - _get_title_button_height()) - 1);
if (v_scroll_value > 1 || v_scroll_below_max) {
int hint_height = theme_cache.scroll_hint->get_height();
if ((scroll_hint_mode == SCROLL_HINT_MODE_BOTH || scroll_hint_mode == SCROLL_HINT_MODE_TOP) && v_scroll_value > 1) {
diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp
index e338a5e594b..aae90f29f92 100644
--- a/scene/theme/default_theme.cpp
+++ b/scene/theme/default_theme.cpp
@@ -959,6 +959,7 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const
theme->set_stylebox("selected_focus", "ItemList", make_flat_stylebox(style_selected_color));
theme->set_stylebox("cursor", "ItemList", focus);
theme->set_stylebox("cursor_unfocused", "ItemList", focus);
+ theme->set_icon("scroll_hint", "ItemList", icons["scroll_hint_vertical"]);
theme->set_constant("outline_size", "ItemList", 0);