Merge pull request #113574 from YeldhamDev/take_the_hint

Enable scroll hints for several parts of the editor
This commit is contained in:
Rémi Verschelde 2025-12-09 19:32:11 +01:00
commit d09a3d83ff
No known key found for this signature in database
GPG key ID: C3336907360768E1
35 changed files with 334 additions and 93 deletions

View file

@ -85,7 +85,6 @@
<member name="available_layouts" type="int" setter="set_available_layouts" getter="get_available_layouts" enum="EditorDock.DockLayout" is_bitfield="true" default="5">
The available layouts for this dock, as a bitmask. By default, the dock allows vertical and floating layouts.
</member>
<member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="closable" type="bool" setter="set_closable" getter="is_closable" default="false">
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.
</member>

View file

@ -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.
</member>
<member name="scroll_hint_mode" type="int" setter="set_scroll_hint_mode" getter="get_scroll_hint_mode" enum="ItemList.ScrollHintMode" default="0">
The way which scroll hints (indicators that show that the content can still be scrolled in a certain direction) will be shown.
</member>
<member name="select_mode" type="int" setter="set_select_mode" getter="get_select_mode" enum="ItemList.SelectMode" default="0">
Allows single or multiple item selection. See the [enum SelectMode] constants.
</member>
<member name="text_overrun_behavior" type="int" setter="set_text_overrun_behavior" getter="get_text_overrun_behavior" enum="TextServer.OverrunBehavior" default="3">
The clipping behavior when the text exceeds an item's bounding rectangle.
</member>
<member name="tile_scroll_hint" type="bool" setter="set_tile_scroll_hint" getter="is_scroll_hint_tiled" default="false">
If [code]true[/code], the scroll hint texture will be tiled instead of stretched. See [member scroll_hint_mode].
</member>
<member name="wraparound_items" type="bool" setter="set_wraparound_items" getter="has_wraparound_items" default="true">
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 @@
<constant name="SELECT_TOGGLE" value="2" enum="SelectMode">
Allows selecting multiple items by toggling them on and off.
</constant>
<constant name="SCROLL_HINT_MODE_DISABLED" value="0" enum="ScrollHintMode">
Scroll hints will never be shown.
</constant>
<constant name="SCROLL_HINT_MODE_BOTH" value="1" enum="ScrollHintMode">
Scroll hints will be shown at the top and bottom.
</constant>
<constant name="SCROLL_HINT_MODE_TOP" value="2" enum="ScrollHintMode">
Only the top scroll hint will be shown.
</constant>
<constant name="SCROLL_HINT_MODE_BOTTOM" value="3" enum="ScrollHintMode">
Only the bottom scroll hint will be shown.
</constant>
</constants>
<theme_items>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.65, 0.65, 0.65, 1)">
@ -529,6 +547,9 @@
<theme_item name="font_size" data_type="font_size" type="int">
Font size of the item's text.
</theme_item>
<theme_item name="scroll_hint" data_type="icon" type="Texture2D">
The indicator that will be shown when the content can still be scrolled. See [member scroll_hint_mode].
</theme_item>
<theme_item name="cursor" data_type="style" type="StyleBox">
[StyleBox] used for the cursor, when the [ItemList] is being focused.
</theme_item>

View file

@ -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));

View file

@ -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;

View file

@ -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);

View file

@ -70,7 +70,6 @@ EditorDebuggerNode::EditorDebuggerNode() {
set_global(false);
set_transient(true);
set_clip_contents(false);
_update_margins();
if (!singleton) {

View file

@ -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);

View file

@ -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<String> &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() {

View file

@ -105,7 +105,6 @@ void EditorDock::_bind_methods() {
}
EditorDock::EditorDock() {
set_clip_contents(true);
add_user_signal(MethodInfo("tab_style_changed"));
}

View file

@ -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));

View file

@ -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;

View file

@ -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<Node *> &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() {

View file

@ -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));

View file

@ -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));
}

View file

@ -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.

View file

@ -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);

View file

@ -4421,10 +4421,11 @@ List<Node *> 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);

View file

@ -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();

View file

@ -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() {

View file

@ -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);

View file

@ -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"));

View file

@ -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!"));

View file

@ -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();

View file

@ -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);

View file

@ -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<Shortcut> ED_SHORTCUT_AND_COMMAND(const String &p_path, const String &p_name, Key p_keycode, String p_command_name) {

View file

@ -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);

View file

@ -1588,6 +1588,7 @@ void ThemeClassic::populate_editor_styles(const Ref<EditorTheme> &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<StyleBoxFlat> style_content_panel_vp = p_config.content_panel_style->duplicate();

View file

@ -1861,6 +1861,33 @@ void ThemeModern::populate_editor_styles(const Ref<EditorTheme> &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);

View file

@ -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";

View file

@ -208,7 +208,6 @@ namespace GodotTools.Build
AvailableLayouts = DockLayout.Horizontal | DockLayout.Floating;
Global = false;
Transient = true;
ClipContents = false;
}
public override void _Ready()

View file

@ -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);

View file

@ -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<StyleBox> cursor_style;
Ref<StyleBox> cursor_focus_style;
Color guide_color;
Ref<Texture2D> 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);

View file

@ -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);
}

View file

@ -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) {

View file

@ -959,6 +959,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &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);