feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -307,6 +307,7 @@ EditorBottomPanel::EditorBottomPanel() {
|
|||
|
||||
left_button = memnew(Button);
|
||||
left_button->set_tooltip_text(TTR("Scroll Left\nHold Ctrl to scroll to the begin.\nHold Shift to scroll one page."));
|
||||
left_button->set_accessibility_name(TTRC("Scroll Left"));
|
||||
left_button->set_theme_type_variation("BottomPanelButton");
|
||||
left_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
left_button->connect(SceneStringName(pressed), callable_mp(this, &EditorBottomPanel::_scroll).bind(false));
|
||||
|
|
@ -323,6 +324,7 @@ EditorBottomPanel::EditorBottomPanel() {
|
|||
|
||||
right_button = memnew(Button);
|
||||
right_button->set_tooltip_text(TTR("Scroll Right\nHold Ctrl to scroll to the end.\nHold Shift to scroll one page."));
|
||||
right_button->set_accessibility_name(TTRC("Scroll Right"));
|
||||
right_button->set_theme_type_variation("BottomPanelButton");
|
||||
right_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
right_button->connect(SceneStringName(pressed), callable_mp(this, &EditorBottomPanel::_scroll).bind(true));
|
||||
|
|
@ -354,6 +356,7 @@ EditorBottomPanel::EditorBottomPanel() {
|
|||
pin_button->set_theme_type_variation("FlatMenuButton");
|
||||
pin_button->set_toggle_mode(true);
|
||||
pin_button->set_tooltip_text(TTR("Pin Bottom Panel Switching"));
|
||||
pin_button->set_accessibility_name(TTRC("Pin Bottom Panel"));
|
||||
pin_button->connect(SceneStringName(toggled), callable_mp(this, &EditorBottomPanel::_pin_button_toggled));
|
||||
|
||||
expand_button = memnew(Button);
|
||||
|
|
@ -361,6 +364,7 @@ EditorBottomPanel::EditorBottomPanel() {
|
|||
expand_button->hide();
|
||||
expand_button->set_theme_type_variation("FlatMenuButton");
|
||||
expand_button->set_toggle_mode(true);
|
||||
expand_button->set_accessibility_name(TTRC("Expand Bottom Panel"));
|
||||
expand_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/bottom_panel_expand", TTRC("Expand Bottom Panel"), KeyModifierMask::SHIFT | Key::F12));
|
||||
expand_button->connect(SceneStringName(toggled), callable_mp(this, &EditorBottomPanel::_expand_button_toggled));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_BOTTOM_PANEL_H
|
||||
#define EDITOR_BOTTOM_PANEL_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/panel_container.h"
|
||||
|
||||
|
|
@ -90,5 +89,3 @@ public:
|
|||
|
||||
EditorBottomPanel();
|
||||
};
|
||||
|
||||
#endif // EDITOR_BOTTOM_PANEL_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_DIR_DIALOG_H
|
||||
#define EDITOR_DIR_DIALOG_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/dialogs.h"
|
||||
|
||||
|
|
@ -73,5 +72,3 @@ public:
|
|||
|
||||
EditorDirDialog();
|
||||
};
|
||||
|
||||
#endif // EDITOR_DIR_DIALOG_H
|
||||
|
|
|
|||
|
|
@ -65,7 +65,15 @@ void EditorFileDialog::_native_popup() {
|
|||
} else if (access == ACCESS_USERDATA) {
|
||||
root = OS::get_singleton()->get_user_data_dir();
|
||||
}
|
||||
DisplayServer::get_singleton()->file_dialog_with_options_show(get_translated_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), processed_filters, _get_options(), callable_mp(this, &EditorFileDialog::_native_dialog_cb));
|
||||
|
||||
// Attach native file dialog to first persistent parent window.
|
||||
Window *w = (is_transient() || is_transient_to_focused()) ? get_parent_visible_window() : nullptr;
|
||||
while (w && w->get_flag(FLAG_POPUP) && w->get_parent_visible_window()) {
|
||||
w = w->get_parent_visible_window();
|
||||
}
|
||||
DisplayServer::WindowID wid = w ? w->get_window_id() : DisplayServer::INVALID_WINDOW_ID;
|
||||
|
||||
DisplayServer::get_singleton()->file_dialog_with_options_show(get_translated_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), processed_filters, _get_options(), callable_mp(this, &EditorFileDialog::_native_dialog_cb), wid);
|
||||
}
|
||||
|
||||
void EditorFileDialog::popup(const Rect2i &p_rect) {
|
||||
|
|
@ -134,9 +142,9 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
|
|||
} else if (filters.size() > 1 && p_filter == 0) {
|
||||
// Match all filters.
|
||||
for (int i = 0; i < filters.size(); i++) {
|
||||
String flt = filters[i].get_slice(";", 0);
|
||||
String flt = filters[i].get_slicec(';', 0);
|
||||
for (int j = 0; j < flt.get_slice_count(","); j++) {
|
||||
String str = flt.get_slice(",", j).strip_edges();
|
||||
String str = flt.get_slicec(',', j).strip_edges();
|
||||
if (f.matchn(str)) {
|
||||
valid = true;
|
||||
break;
|
||||
|
|
@ -152,10 +160,10 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
|
|||
idx--;
|
||||
}
|
||||
if (idx >= 0 && idx < filters.size()) {
|
||||
String flt = filters[idx].get_slice(";", 0);
|
||||
String flt = filters[idx].get_slicec(';', 0);
|
||||
int filter_slice_count = flt.get_slice_count(",");
|
||||
for (int j = 0; j < filter_slice_count; j++) {
|
||||
String str = (flt.get_slice(",", j).strip_edges());
|
||||
String str = flt.get_slicec(',', j).strip_edges();
|
||||
if (f.matchn(str)) {
|
||||
valid = true;
|
||||
break;
|
||||
|
|
@ -163,8 +171,8 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
|
|||
}
|
||||
|
||||
if (!valid && filter_slice_count > 0) {
|
||||
String str = (flt.get_slice(",", 0).strip_edges());
|
||||
f += str.substr(1, str.length() - 1);
|
||||
String str = flt.get_slicec(',', 0).strip_edges();
|
||||
f += str.substr(1);
|
||||
file->set_text(f.get_file());
|
||||
valid = true;
|
||||
}
|
||||
|
|
@ -176,8 +184,8 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
|
|||
// Add first extension of filter if no valid extension is found.
|
||||
if (!valid) {
|
||||
int idx = p_filter;
|
||||
String flt = filters[idx].get_slice(";", 0);
|
||||
String ext = flt.get_slice(",", 0).strip_edges().get_extension();
|
||||
String flt = filters[idx].get_slicec(';', 0);
|
||||
String ext = flt.get_slicec(',', 0).strip_edges().get_extension();
|
||||
f += "." + ext;
|
||||
}
|
||||
emit_signal(SNAME("file_selected"), f);
|
||||
|
|
@ -586,7 +594,7 @@ void EditorFileDialog::_action_pressed() {
|
|||
} else if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_OPEN_DIR) {
|
||||
String path = dir_access->get_current_dir();
|
||||
|
||||
path = path.replace("\\", "/");
|
||||
path = path.replace_char('\\', '/');
|
||||
|
||||
for (int i = 0; i < item_list->get_item_count(); i++) {
|
||||
if (item_list->is_selected(i)) {
|
||||
|
|
@ -612,9 +620,9 @@ void EditorFileDialog::_action_pressed() {
|
|||
} else if (filters.size() > 1 && filter->get_selected() == 0) {
|
||||
// Match all filters.
|
||||
for (int i = 0; i < filters.size(); i++) {
|
||||
String flt = filters[i].get_slice(";", 0);
|
||||
String flt = filters[i].get_slicec(';', 0);
|
||||
for (int j = 0; j < flt.get_slice_count(","); j++) {
|
||||
String str = flt.get_slice(",", j).strip_edges();
|
||||
String str = flt.get_slicec(',', j).strip_edges();
|
||||
if (f.matchn(str)) {
|
||||
valid = true;
|
||||
break;
|
||||
|
|
@ -630,10 +638,10 @@ void EditorFileDialog::_action_pressed() {
|
|||
idx--;
|
||||
}
|
||||
if (idx >= 0 && idx < filters.size()) {
|
||||
String flt = filters[idx].get_slice(";", 0);
|
||||
String flt = filters[idx].get_slicec(';', 0);
|
||||
int filter_slice_count = flt.get_slice_count(",");
|
||||
for (int j = 0; j < filter_slice_count; j++) {
|
||||
String str = (flt.get_slice(",", j).strip_edges());
|
||||
String str = (flt.get_slicec(',', j).strip_edges());
|
||||
if (f.matchn(str)) {
|
||||
valid = true;
|
||||
break;
|
||||
|
|
@ -641,8 +649,8 @@ void EditorFileDialog::_action_pressed() {
|
|||
}
|
||||
|
||||
if (!valid && filter_slice_count > 0) {
|
||||
String str = (flt.get_slice(",", 0).strip_edges());
|
||||
f += str.substr(1, str.length() - 1);
|
||||
String str = flt.get_slicec(',', 0).strip_edges();
|
||||
f += str.substr(1);
|
||||
_request_single_thumbnail(get_current_dir().path_join(f.get_file()));
|
||||
file->set_text(f.get_file());
|
||||
valid = true;
|
||||
|
|
@ -663,8 +671,8 @@ void EditorFileDialog::_action_pressed() {
|
|||
// Add first extension of filter if no valid extension is found.
|
||||
if (!valid) {
|
||||
int idx = filter->get_selected();
|
||||
String flt = filters[idx].get_slice(";", 0);
|
||||
String ext = flt.get_slice(",", 0).strip_edges().get_extension();
|
||||
String flt = filters[idx].get_slicec(';', 0);
|
||||
String ext = flt.get_slicec(',', 0).strip_edges().get_extension();
|
||||
f += "." + ext;
|
||||
}
|
||||
|
||||
|
|
@ -762,7 +770,7 @@ void EditorFileDialog::_items_clear_selection(const Vector2 &p_pos, MouseButton
|
|||
void EditorFileDialog::_push_history() {
|
||||
local_history.resize(local_history_pos + 1);
|
||||
String new_path = dir_access->get_current_dir();
|
||||
if (local_history.size() == 0 || new_path != local_history[local_history_pos]) {
|
||||
if (local_history.is_empty() || new_path != local_history[local_history_pos]) {
|
||||
local_history.push_back(new_path);
|
||||
local_history_pos++;
|
||||
dir_prev->set_disabled(local_history_pos == 0);
|
||||
|
|
@ -932,7 +940,7 @@ bool EditorFileDialog::_is_open_should_be_disabled() {
|
|||
}
|
||||
|
||||
Vector<int> items = item_list->get_selected_items();
|
||||
if (items.size() == 0) {
|
||||
if (items.is_empty()) {
|
||||
return mode != FILE_MODE_OPEN_DIR; // In "Open folder" mode, having nothing selected picks the current folder.
|
||||
}
|
||||
|
||||
|
|
@ -1097,9 +1105,9 @@ void EditorFileDialog::update_file_list() {
|
|||
} else if (filters.size() > 1 && filter->get_selected() == 0) {
|
||||
// match all filters
|
||||
for (int i = 0; i < filters.size(); i++) {
|
||||
String f = filters[i].get_slice(";", 0);
|
||||
String f = filters[i].get_slicec(';', 0);
|
||||
for (int j = 0; j < f.get_slice_count(","); j++) {
|
||||
patterns.push_back(f.get_slice(",", j).strip_edges());
|
||||
patterns.push_back(f.get_slicec(',', j).strip_edges());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1109,9 +1117,9 @@ void EditorFileDialog::update_file_list() {
|
|||
}
|
||||
|
||||
if (idx >= 0 && idx < filters.size()) {
|
||||
String f = filters[idx].get_slice(";", 0);
|
||||
String f = filters[idx].get_slicec(';', 0);
|
||||
for (int j = 0; j < f.get_slice_count(","); j++) {
|
||||
patterns.push_back(f.get_slice(",", j).strip_edges());
|
||||
patterns.push_back(f.get_slicec(',', j).strip_edges());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1428,7 +1436,7 @@ void EditorFileDialog::set_current_path(const String &p_path) {
|
|||
set_current_file(p_path);
|
||||
} else {
|
||||
String path_dir = p_path.substr(0, pos);
|
||||
String path_file = p_path.substr(pos + 1, p_path.length());
|
||||
String path_file = p_path.substr(pos + 1);
|
||||
set_current_dir(path_dir);
|
||||
set_current_file(path_file);
|
||||
}
|
||||
|
|
@ -2040,6 +2048,7 @@ void EditorFileDialog::_update_option_controls() {
|
|||
for (const EditorFileDialog::Option &opt : options) {
|
||||
if (opt.values.is_empty()) {
|
||||
CheckBox *cb = memnew(CheckBox);
|
||||
cb->set_accessibility_name(opt.name);
|
||||
cb->set_pressed(opt.default_idx);
|
||||
cb->set_text(opt.name);
|
||||
flow_checkbox_options->add_child(cb);
|
||||
|
|
@ -2048,12 +2057,14 @@ void EditorFileDialog::_update_option_controls() {
|
|||
} else {
|
||||
Label *lbl = memnew(Label);
|
||||
lbl->set_text(opt.name);
|
||||
lbl->set_focus_mode(Control::FOCUS_NONE);
|
||||
grid_select_options->add_child(lbl);
|
||||
|
||||
OptionButton *ob = memnew(OptionButton);
|
||||
for (const String &val : opt.values) {
|
||||
ob->add_item(val);
|
||||
}
|
||||
ob->set_accessibility_name(opt.name);
|
||||
ob->select(opt.default_idx);
|
||||
grid_select_options->add_child(ob);
|
||||
ob->connect(SceneStringName(item_selected), callable_mp(this, &EditorFileDialog::_option_changed_item_selected).bind(opt.name));
|
||||
|
|
@ -2393,12 +2404,15 @@ EditorFileDialog::EditorFileDialog() {
|
|||
|
||||
dir_prev = memnew(Button);
|
||||
dir_prev->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
dir_prev->set_accessibility_name(TTRC("Previous"));
|
||||
dir_prev->set_tooltip_text(TTR("Go to previous folder."));
|
||||
dir_next = memnew(Button);
|
||||
dir_next->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
dir_next->set_accessibility_name(TTRC("Next"));
|
||||
dir_next->set_tooltip_text(TTR("Go to next folder."));
|
||||
dir_up = memnew(Button);
|
||||
dir_up->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
dir_up->set_accessibility_name(TTRC("Parent Folder"));
|
||||
dir_up->set_tooltip_text(TTR("Go to parent folder."));
|
||||
|
||||
pathhb->add_child(dir_prev);
|
||||
|
|
@ -2410,6 +2424,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
dir_up->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::_go_up));
|
||||
|
||||
Label *l = memnew(Label(TTR("Path:")));
|
||||
l->set_focus_mode(Control::FOCUS_NONE);
|
||||
l->set_theme_type_variation("HeaderSmall");
|
||||
pathhb->add_child(l);
|
||||
|
||||
|
|
@ -2418,10 +2433,12 @@ EditorFileDialog::EditorFileDialog() {
|
|||
|
||||
dir = memnew(LineEdit);
|
||||
dir->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
|
||||
dir->set_accessibility_name(TTRC("Directory Path"));
|
||||
pathhb->add_child(dir);
|
||||
|
||||
refresh = memnew(Button);
|
||||
refresh->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
refresh->set_accessibility_name(TTRC("Refresh Files"));
|
||||
refresh->set_tooltip_text(TTR("Refresh files."));
|
||||
refresh->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::update_file_list));
|
||||
pathhb->add_child(refresh);
|
||||
|
|
@ -2429,6 +2446,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
favorite = memnew(Button);
|
||||
favorite->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
favorite->set_toggle_mode(true);
|
||||
favorite->set_accessibility_name(TTRC("(Un)favorite Folder"));
|
||||
favorite->set_tooltip_text(TTR("(Un)favorite current folder."));
|
||||
favorite->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::_favorite_pressed));
|
||||
pathhb->add_child(favorite);
|
||||
|
|
@ -2438,6 +2456,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
|
||||
drives = memnew(OptionButton);
|
||||
drives->connect(SceneStringName(item_selected), callable_mp(this, &EditorFileDialog::_select_drive));
|
||||
drives->set_accessibility_name(TTRC("Current Drive"));
|
||||
pathhb->add_child(drives);
|
||||
|
||||
makedir_sep = memnew(VSeparator);
|
||||
|
|
@ -2445,6 +2464,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
|
||||
makedir = memnew(Button);
|
||||
makedir->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
makedir->set_accessibility_name(TTRC("Create Folder"));
|
||||
makedir->set_tooltip_text(TTR("Create a new folder."));
|
||||
makedir->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::_make_dir));
|
||||
pathhb->add_child(makedir);
|
||||
|
|
@ -2480,16 +2500,19 @@ EditorFileDialog::EditorFileDialog() {
|
|||
fav_vb->add_child(fav_hb);
|
||||
|
||||
l = memnew(Label(TTR("Favorites:")));
|
||||
l->set_focus_mode(Control::FOCUS_NONE);
|
||||
l->set_theme_type_variation("HeaderSmall");
|
||||
fav_hb->add_child(l);
|
||||
|
||||
fav_hb->add_spacer();
|
||||
fav_up = memnew(Button);
|
||||
fav_up->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
fav_up->set_accessibility_name(TTRC("Move Up"));
|
||||
fav_hb->add_child(fav_up);
|
||||
fav_up->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::_favorite_move_up));
|
||||
fav_down = memnew(Button);
|
||||
fav_down->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
fav_down->set_accessibility_name(TTRC("Move Down"));
|
||||
fav_hb->add_child(fav_down);
|
||||
fav_down->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::_favorite_move_down));
|
||||
|
||||
|
|
@ -2498,6 +2521,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
fav_vb->add_child(favorites);
|
||||
favorites->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
favorites->set_theme_type_variation("ItemListSecondary");
|
||||
favorites->set_accessibility_name(TTRC("Favorites"));
|
||||
favorites->connect(SceneStringName(item_selected), callable_mp(this, &EditorFileDialog::_favorite_selected));
|
||||
|
||||
VBoxContainer *rec_vb = memnew(VBoxContainer);
|
||||
|
|
@ -2508,6 +2532,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
recent->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
|
||||
recent->set_allow_reselect(true);
|
||||
recent->set_theme_type_variation("ItemListSecondary");
|
||||
recent->set_accessibility_name(TTRC("Recent"));
|
||||
rec_vb->add_margin_child(TTR("Recent:"), recent, true);
|
||||
recent->connect(SceneStringName(item_selected), callable_mp(this, &EditorFileDialog::_recent_selected));
|
||||
|
||||
|
|
@ -2526,6 +2551,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
lower_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
l = memnew(Label(TTR("Directories & Files:")));
|
||||
l->set_focus_mode(Control::FOCUS_NONE);
|
||||
l->set_theme_type_variation("HeaderSmall");
|
||||
l->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
|
|
@ -2535,6 +2561,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
show_hidden->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
show_hidden->set_toggle_mode(true);
|
||||
show_hidden->set_pressed(is_showing_hidden_files());
|
||||
show_hidden->set_accessibility_name(TTRC("Show Hidden Files"));
|
||||
show_hidden->set_tooltip_text(TTR("Toggle the visibility of hidden files."));
|
||||
show_hidden->connect(SceneStringName(toggled), callable_mp(this, &EditorFileDialog::set_show_hidden_files));
|
||||
lower_hb->add_child(show_hidden);
|
||||
|
|
@ -2550,6 +2577,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
mode_thumbnails->set_toggle_mode(true);
|
||||
mode_thumbnails->set_pressed(display_mode == DISPLAY_THUMBNAILS);
|
||||
mode_thumbnails->set_button_group(view_mode_group);
|
||||
mode_thumbnails->set_accessibility_name(TTRC("View as Thumbnails"));
|
||||
mode_thumbnails->set_tooltip_text(TTR("View items as a grid of thumbnails."));
|
||||
lower_hb->add_child(mode_thumbnails);
|
||||
|
||||
|
|
@ -2559,6 +2587,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
mode_list->set_toggle_mode(true);
|
||||
mode_list->set_pressed(display_mode == DISPLAY_LIST);
|
||||
mode_list->set_button_group(view_mode_group);
|
||||
mode_list->set_accessibility_name(TTRC("View as List"));
|
||||
mode_list->set_tooltip_text(TTR("View items as a list."));
|
||||
lower_hb->add_child(mode_list);
|
||||
|
||||
|
|
@ -2568,12 +2597,14 @@ EditorFileDialog::EditorFileDialog() {
|
|||
file_sort_button->set_flat(false);
|
||||
file_sort_button->set_theme_type_variation("FlatMenuButton");
|
||||
file_sort_button->set_tooltip_text(TTR("Sort files"));
|
||||
file_sort_button->set_accessibility_name(TTRC("Sort Files"));
|
||||
|
||||
show_search_filter_button = memnew(Button);
|
||||
show_search_filter_button->set_theme_type_variation(SceneStringName(FlatButton));
|
||||
show_search_filter_button->set_toggle_mode(true);
|
||||
show_search_filter_button->set_pressed(false);
|
||||
show_search_filter_button->set_tooltip_text(TTR("Toggle the visibility of the filter for file names."));
|
||||
show_search_filter_button->set_accessibility_name(TTRC("Show Search Filters"));
|
||||
show_search_filter_button->connect(SceneStringName(toggled), callable_mp(this, &EditorFileDialog::set_show_search_filter));
|
||||
lower_hb->add_child(show_search_filter_button);
|
||||
|
||||
|
|
@ -2599,6 +2630,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
item_list->connect("item_clicked", callable_mp(this, &EditorFileDialog::_item_list_item_rmb_clicked));
|
||||
item_list->connect("empty_clicked", callable_mp(this, &EditorFileDialog::_item_list_empty_clicked));
|
||||
item_list->set_allow_rmb_select(true);
|
||||
item_list->set_accessibility_name(TTRC("Directories and Files"));
|
||||
|
||||
list_vb->add_child(item_list);
|
||||
|
||||
|
|
@ -2621,6 +2653,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
filter_box = memnew(LineEdit);
|
||||
filter_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
filter_box->set_placeholder(TTR("Filter"));
|
||||
filter_box->set_accessibility_name(TTRC("Filename Filter"));
|
||||
filter_hb->add_child(filter_box);
|
||||
filter_hb->set_visible(false);
|
||||
item_vb->add_child(filter_hb);
|
||||
|
|
@ -2628,6 +2661,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
file_box = memnew(HBoxContainer);
|
||||
|
||||
l = memnew(Label(TTR("File:")));
|
||||
l->set_focus_mode(Control::FOCUS_NONE);
|
||||
l->set_theme_type_variation("HeaderSmall");
|
||||
file_box->add_child(l);
|
||||
|
||||
|
|
@ -2635,11 +2669,13 @@ EditorFileDialog::EditorFileDialog() {
|
|||
file->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
|
||||
file->set_stretch_ratio(4);
|
||||
file->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
file->set_accessibility_name(TTRC("File Name"));
|
||||
file_box->add_child(file);
|
||||
filter = memnew(OptionButton);
|
||||
filter->set_stretch_ratio(3);
|
||||
filter->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
filter->set_clip_text(true); // Too many extensions overflow it.
|
||||
filter->set_accessibility_name(TTRC("File Type Filter"));
|
||||
file_box->add_child(filter);
|
||||
file_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
item_vb->add_child(file_box);
|
||||
|
|
@ -2677,6 +2713,7 @@ EditorFileDialog::EditorFileDialog() {
|
|||
|
||||
makedirname = memnew(LineEdit);
|
||||
makedirname->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
|
||||
makedirname->set_accessibility_name(TTRC("Name"));
|
||||
makevb->add_margin_child(TTR("Name:"), makedirname);
|
||||
add_child(makedialog);
|
||||
makedialog->register_text_enter(makedirname);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_FILE_DIALOG_H
|
||||
#define EDITOR_FILE_DIALOG_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/dir_access.h"
|
||||
#include "editor/file_info.h"
|
||||
|
|
@ -378,5 +377,3 @@ public:
|
|||
VARIANT_ENUM_CAST(EditorFileDialog::FileMode);
|
||||
VARIANT_ENUM_CAST(EditorFileDialog::Access);
|
||||
VARIANT_ENUM_CAST(EditorFileDialog::DisplayMode);
|
||||
|
||||
#endif // EDITOR_FILE_DIALOG_H
|
||||
|
|
|
|||
|
|
@ -128,7 +128,6 @@ void EditorObjectSelector::update_path() {
|
|||
}
|
||||
|
||||
Ref<Texture2D> obj_icon = EditorNode::get_singleton()->get_object_icon(obj);
|
||||
|
||||
if (obj_icon.is_valid()) {
|
||||
current_object_icon->set_texture(obj_icon);
|
||||
}
|
||||
|
|
@ -148,7 +147,7 @@ void EditorObjectSelector::update_path() {
|
|||
if (name.is_empty()) {
|
||||
name = r->get_class();
|
||||
}
|
||||
} else if (obj->is_class("EditorDebuggerRemoteObject")) {
|
||||
} else if (obj->is_class("EditorDebuggerRemoteObjects")) {
|
||||
name = obj->call("get_title");
|
||||
} else if (Object::cast_to<Node>(obj)) {
|
||||
name = Object::cast_to<Node>(obj)->get_name();
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_OBJECT_SELECTOR_H
|
||||
#define EDITOR_OBJECT_SELECTOR_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
|
|
@ -68,5 +67,3 @@ public:
|
|||
|
||||
EditorObjectSelector(EditorSelectionHistory *p_history);
|
||||
};
|
||||
|
||||
#endif // EDITOR_OBJECT_SELECTOR_H
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ EditorQuickOpenDialog::EditorQuickOpenDialog() {
|
|||
search_box = memnew(LineEdit);
|
||||
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
search_box->set_placeholder(TTR("Search files..."));
|
||||
search_box->set_accessibility_name(TTRC("Search"));
|
||||
search_box->set_clear_button_enabled(true);
|
||||
mc->add_child(search_box);
|
||||
}
|
||||
|
|
@ -278,6 +279,7 @@ QuickOpenResultContainer::QuickOpenResultContainer() {
|
|||
bottom_bar->add_child(vsep);
|
||||
|
||||
display_mode_toggle = memnew(Button);
|
||||
display_mode_toggle->set_accessibility_name(TTRC("Display Mode"));
|
||||
style_button(display_mode_toggle);
|
||||
display_mode_toggle->connect(SceneStringName(pressed), callable_mp(this, &QuickOpenResultContainer::_toggle_display_mode));
|
||||
bottom_bar->add_child(display_mode_toggle);
|
||||
|
|
@ -343,18 +345,31 @@ void QuickOpenResultContainer::init(const Vector<StringName> &p_base_types) {
|
|||
// Load history when opening for the first time.
|
||||
file_type_icons.insert(SNAME("__default_icon"), get_editor_theme_icon(SNAME("Object")));
|
||||
|
||||
bool history_modified = false;
|
||||
List<String> history_keys;
|
||||
history_file->get_section_keys("selected_history", &history_keys);
|
||||
for (const String &type : history_keys) {
|
||||
const StringName type_name = type;
|
||||
const PackedStringArray paths = history_file->get_value("selected_history", type);
|
||||
|
||||
PackedStringArray cleaned_paths;
|
||||
cleaned_paths.resize(paths.size());
|
||||
|
||||
Vector<QuickOpenResultCandidate> loaded_candidates;
|
||||
loaded_candidates.resize(paths.size());
|
||||
{
|
||||
QuickOpenResultCandidate *candidates_write = loaded_candidates.ptrw();
|
||||
String *cleanup_write = cleaned_paths.ptrw();
|
||||
int i = 0;
|
||||
for (const String &path : paths) {
|
||||
for (String path : paths) {
|
||||
if (path.begins_with("uid://")) {
|
||||
ResourceUID::ID id = ResourceUID::get_singleton()->text_to_id(path);
|
||||
if (!ResourceUID::get_singleton()->has_id(id)) {
|
||||
continue;
|
||||
}
|
||||
path = ResourceUID::get_singleton()->get_id_path(id);
|
||||
}
|
||||
|
||||
if (!ResourceLoader::exists(path)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -363,22 +378,62 @@ void QuickOpenResultContainer::init(const Vector<StringName> &p_base_types) {
|
|||
QuickOpenResultCandidate candidate;
|
||||
_setup_candidate(candidate, path);
|
||||
candidates_write[i] = candidate;
|
||||
cleanup_write[i] = path;
|
||||
i++;
|
||||
}
|
||||
loaded_candidates.resize(i);
|
||||
cleaned_paths.resize(i);
|
||||
selected_history.insert(type, loaded_candidates);
|
||||
|
||||
if (i < paths.size()) {
|
||||
// Some paths removed, need to update history.
|
||||
if (i == 0) {
|
||||
history_file->erase_section_key("selected_history", type);
|
||||
} else {
|
||||
history_file->set_value("selected_history", type, cleaned_paths);
|
||||
}
|
||||
history_modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (history_modified) {
|
||||
history_file->save(_get_cache_file_path());
|
||||
}
|
||||
}
|
||||
|
||||
_create_initial_results();
|
||||
}
|
||||
|
||||
void QuickOpenResultContainer::_sort_filepaths(int p_max_results) {
|
||||
struct FilepathComparator {
|
||||
bool operator()(const String &p_lhs, const String &p_rhs) const {
|
||||
// Sort on (length, alphanumeric) to prioritize shorter filepaths
|
||||
return p_lhs.length() == p_rhs.length() ? p_lhs < p_rhs : p_lhs.length() < p_rhs.length();
|
||||
}
|
||||
};
|
||||
|
||||
SortArray<String, FilepathComparator> sorter;
|
||||
if (filepaths.size() > p_max_results) {
|
||||
sorter.partial_sort(0, filepaths.size(), p_max_results, filepaths.ptrw());
|
||||
} else {
|
||||
sorter.sort(filepaths.ptrw(), filepaths.size());
|
||||
}
|
||||
}
|
||||
|
||||
void QuickOpenResultContainer::_create_initial_results() {
|
||||
file_type_icons.clear();
|
||||
file_type_icons.insert(SNAME("__default_icon"), get_editor_theme_icon(SNAME("Object")));
|
||||
filepaths.clear();
|
||||
filetypes.clear();
|
||||
history_set.clear();
|
||||
Vector<QuickOpenResultCandidate> *history = _get_history();
|
||||
if (history) {
|
||||
for (const QuickOpenResultCandidate &candidate : *history) {
|
||||
history_set.insert(candidate.file_path);
|
||||
}
|
||||
}
|
||||
_find_filepaths_in_folder(EditorFileSystem::get_singleton()->get_filesystem(), include_addons_toggle->is_pressed());
|
||||
_sort_filepaths(result_items.size());
|
||||
max_total_results = MIN(filepaths.size(), result_items.size());
|
||||
update_results();
|
||||
}
|
||||
|
|
@ -416,25 +471,26 @@ void QuickOpenResultContainer::set_query_and_update(const String &p_query) {
|
|||
update_results();
|
||||
}
|
||||
|
||||
void QuickOpenResultContainer::_setup_candidate(QuickOpenResultCandidate &p_candidate, const String &p_filepath) {
|
||||
ResourceUID::ID id = EditorFileSystem::get_singleton()->get_file_uid(p_filepath);
|
||||
if (id == ResourceUID::INVALID_ID) {
|
||||
p_candidate.file_path = p_filepath;
|
||||
} else {
|
||||
p_candidate.file_path = ResourceUID::get_singleton()->id_to_text(id);
|
||||
Vector<QuickOpenResultCandidate> *QuickOpenResultContainer::_get_history() {
|
||||
if (base_types.size() == 1) {
|
||||
return selected_history.lookup_ptr(base_types[0]);
|
||||
}
|
||||
p_candidate.result = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void QuickOpenResultContainer::_setup_candidate(QuickOpenResultCandidate &p_candidate, const String &p_filepath) {
|
||||
p_candidate.file_path = ResourceUID::ensure_path(p_filepath);
|
||||
p_candidate.result = nullptr;
|
||||
StringName actual_type;
|
||||
{
|
||||
StringName *actual_type_ptr = filetypes.lookup_ptr(p_filepath);
|
||||
if (actual_type_ptr) {
|
||||
actual_type = *actual_type_ptr;
|
||||
} else {
|
||||
ERR_PRINT(vformat("EditorQuickOpenDialog: No type for path %s.", p_filepath));
|
||||
ERR_PRINT(vformat("EditorQuickOpenDialog: No type for path %s.", p_candidate.file_path));
|
||||
}
|
||||
}
|
||||
EditorResourcePreview::PreviewItem item = EditorResourcePreview::get_singleton()->get_resource_preview_if_available(p_filepath);
|
||||
EditorResourcePreview::PreviewItem item = EditorResourcePreview::get_singleton()->get_resource_preview_if_available(p_candidate.file_path);
|
||||
if (item.preview.is_valid()) {
|
||||
p_candidate.thumbnail = item.preview;
|
||||
} else if (file_type_icons.has(actual_type)) {
|
||||
|
|
@ -453,7 +509,6 @@ void QuickOpenResultContainer::_setup_candidate(QuickOpenResultCandidate &p_cand
|
|||
}
|
||||
|
||||
void QuickOpenResultContainer::update_results() {
|
||||
showing_history = false;
|
||||
candidates.clear();
|
||||
if (query.is_empty()) {
|
||||
_use_default_candidates();
|
||||
|
|
@ -464,17 +519,18 @@ void QuickOpenResultContainer::update_results() {
|
|||
}
|
||||
|
||||
void QuickOpenResultContainer::_use_default_candidates() {
|
||||
if (filepaths.size() <= SHOW_ALL_FILES_THRESHOLD) {
|
||||
candidates.resize(filepaths.size());
|
||||
QuickOpenResultCandidate *candidates_write = candidates.ptrw();
|
||||
for (const String &filepath : filepaths) {
|
||||
_setup_candidate(*candidates_write++, filepath);
|
||||
Vector<QuickOpenResultCandidate> *history = _get_history();
|
||||
if (history) {
|
||||
candidates.append_array(*history);
|
||||
}
|
||||
int count = candidates.size();
|
||||
candidates.resize(MIN(max_total_results, filepaths.size()));
|
||||
for (const String &filepath : filepaths) {
|
||||
if (count >= max_total_results) {
|
||||
break;
|
||||
}
|
||||
} else if (base_types.size() == 1) {
|
||||
Vector<QuickOpenResultCandidate> *history = selected_history.lookup_ptr(base_types[0]);
|
||||
if (history) {
|
||||
showing_history = true;
|
||||
candidates.append_array(*history);
|
||||
if (!history || !history_set.has(filepath)) {
|
||||
_setup_candidate(candidates.write[count++], filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -524,8 +580,6 @@ void QuickOpenResultContainer::_update_result_items(int p_new_visible_results_co
|
|||
if (!any_results) {
|
||||
if (filepaths.is_empty()) {
|
||||
no_results_label->set_text(TTR("No files found for this type"));
|
||||
} else if (query.is_empty()) {
|
||||
no_results_label->set_text(TTR("Start searching to find files..."));
|
||||
} else {
|
||||
no_results_label->set_text(TTR("No results found"));
|
||||
}
|
||||
|
|
@ -552,7 +606,7 @@ void QuickOpenResultContainer::handle_search_box_input(const Ref<InputEvent> &p_
|
|||
case Key::RIGHT: {
|
||||
if (content_display_mode == QuickOpenDisplayMode::GRID) {
|
||||
// Maybe strip off the shift modifier to allow non-selecting navigation by character?
|
||||
if (key_event->get_modifiers_mask() == 0) {
|
||||
if (key_event->get_modifiers_mask().is_empty()) {
|
||||
move_selection = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -621,7 +675,8 @@ void QuickOpenResultContainer::_select_item(int p_index) {
|
|||
}
|
||||
|
||||
result_items[selection_index]->highlight_item(true);
|
||||
file_details_path->set_text(get_selected() + (showing_history ? TTR(" (recently opened)") : ""));
|
||||
bool in_history = history_set.has(candidates[selection_index].file_path);
|
||||
file_details_path->set_text(get_selected() + (in_history ? TTR(" (recently opened)") : ""));
|
||||
|
||||
const QuickOpenResultItem *item = result_items[selection_index];
|
||||
|
||||
|
|
@ -727,7 +782,7 @@ bool QuickOpenResultContainer::has_nothing_selected() const {
|
|||
|
||||
String QuickOpenResultContainer::get_selected() const {
|
||||
ERR_FAIL_COND_V_MSG(has_nothing_selected(), String(), "Tried to get selected file, but nothing was selected.");
|
||||
return ResourceUID::ensure_path(candidates[selection_index].file_path);
|
||||
return candidates[selection_index].file_path;
|
||||
}
|
||||
|
||||
QuickOpenDisplayMode QuickOpenResultContainer::get_adaptive_display_mode(const Vector<StringName> &p_base_types) {
|
||||
|
|
@ -749,6 +804,11 @@ QuickOpenDisplayMode QuickOpenResultContainer::get_adaptive_display_mode(const V
|
|||
return QuickOpenDisplayMode::LIST;
|
||||
}
|
||||
|
||||
String _get_uid_string(const String &p_filepath) {
|
||||
ResourceUID::ID id = EditorFileSystem::get_singleton()->get_file_uid(p_filepath);
|
||||
return id == ResourceUID::INVALID_ID ? p_filepath : ResourceUID::get_singleton()->id_to_text(id);
|
||||
}
|
||||
|
||||
void QuickOpenResultContainer::save_selected_item() {
|
||||
if (base_types.size() > 1) {
|
||||
// Getting the type of the file and checking which base type it belongs to should be possible.
|
||||
|
|
@ -773,6 +833,7 @@ void QuickOpenResultContainer::save_selected_item() {
|
|||
}
|
||||
|
||||
selected.result = nullptr;
|
||||
history_set.insert(selected.file_path);
|
||||
type_history->insert(0, selected);
|
||||
if (type_history->size() > MAX_HISTORY_SIZE) {
|
||||
type_history->resize(MAX_HISTORY_SIZE);
|
||||
|
|
@ -785,7 +846,7 @@ void QuickOpenResultContainer::save_selected_item() {
|
|||
|
||||
int i = 0;
|
||||
for (const QuickOpenResultCandidate &candidate : *type_history) {
|
||||
paths_write[i] = candidate.file_path;
|
||||
paths_write[i] = _get_uid_string(candidate.file_path);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
@ -796,6 +857,7 @@ void QuickOpenResultContainer::save_selected_item() {
|
|||
void QuickOpenResultContainer::cleanup() {
|
||||
num_visible_results = 0;
|
||||
candidates.clear();
|
||||
history_set.clear();
|
||||
_select_item(-1);
|
||||
|
||||
for (QuickOpenResultItem *item : result_items) {
|
||||
|
|
@ -981,9 +1043,8 @@ QuickOpenResultListItem::QuickOpenResultListItem() {
|
|||
|
||||
void QuickOpenResultListItem::set_content(const QuickOpenResultCandidate &p_candidate, bool p_highlight) {
|
||||
thumbnail->set_texture(p_candidate.thumbnail);
|
||||
const String file_path = ResourceUID::ensure_path(p_candidate.file_path);
|
||||
name->set_text(file_path.get_file());
|
||||
path->set_text(file_path.get_base_dir());
|
||||
name->set_text(p_candidate.file_path.get_file());
|
||||
path->set_text(p_candidate.file_path.get_base_dir());
|
||||
name->reset_highlights();
|
||||
path->reset_highlights();
|
||||
|
||||
|
|
@ -1053,9 +1114,8 @@ QuickOpenResultGridItem::QuickOpenResultGridItem() {
|
|||
|
||||
void QuickOpenResultGridItem::set_content(const QuickOpenResultCandidate &p_candidate, bool p_highlight) {
|
||||
thumbnail->set_texture(p_candidate.thumbnail);
|
||||
const String file_path = ResourceUID::ensure_path(p_candidate.file_path);
|
||||
name->set_text(file_path.get_file());
|
||||
name->set_tooltip_text(file_path);
|
||||
name->set_text(p_candidate.file_path.get_file());
|
||||
name->set_tooltip_text(p_candidate.file_path);
|
||||
name->reset_highlights();
|
||||
|
||||
if (p_highlight && p_candidate.result != nullptr) {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_QUICK_OPEN_DIALOG_H
|
||||
#define EDITOR_QUICK_OPEN_DIALOG_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/oa_hash_map.h"
|
||||
#include "scene/gui/dialogs.h"
|
||||
|
|
@ -107,7 +106,6 @@ protected:
|
|||
void _notification(int p_what);
|
||||
|
||||
private:
|
||||
static constexpr int SHOW_ALL_FILES_THRESHOLD = 30;
|
||||
static constexpr int MAX_HISTORY_SIZE = 20;
|
||||
|
||||
Vector<FuzzySearchResult> search_results;
|
||||
|
|
@ -117,13 +115,13 @@ private:
|
|||
Vector<QuickOpenResultCandidate> candidates;
|
||||
|
||||
OAHashMap<StringName, Vector<QuickOpenResultCandidate>> selected_history;
|
||||
HashSet<String> history_set;
|
||||
|
||||
String query;
|
||||
int selection_index = -1;
|
||||
int num_visible_results = 0;
|
||||
int max_total_results = 0;
|
||||
|
||||
bool showing_history = false;
|
||||
bool never_opened = true;
|
||||
Ref<ConfigFile> history_file;
|
||||
|
||||
|
|
@ -149,9 +147,11 @@ private:
|
|||
static QuickOpenDisplayMode get_adaptive_display_mode(const Vector<StringName> &p_base_types);
|
||||
|
||||
void _ensure_result_vector_capacity();
|
||||
void _sort_filepaths(int p_max_results);
|
||||
void _create_initial_results();
|
||||
void _find_filepaths_in_folder(EditorFileSystemDirectory *p_directory, bool p_include_addons);
|
||||
|
||||
Vector<QuickOpenResultCandidate> *_get_history();
|
||||
void _setup_candidate(QuickOpenResultCandidate &p_candidate, const String &p_filepath);
|
||||
void _setup_candidate(QuickOpenResultCandidate &p_candidate, const FuzzySearchResult &p_result);
|
||||
void _update_fuzzy_search_results();
|
||||
|
|
@ -268,5 +268,3 @@ private:
|
|||
|
||||
void _search_box_text_changed(const String &p_query);
|
||||
};
|
||||
|
||||
#endif // EDITOR_QUICK_OPEN_DIALOG_H
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@
|
|||
#include "scene/gui/menu_button.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
#ifndef XR_DISABLED
|
||||
#include "servers/xr_server.h"
|
||||
#endif // _3D_DISABLED
|
||||
#endif // XR_DISABLED
|
||||
|
||||
EditorRunBar *EditorRunBar::singleton = nullptr;
|
||||
|
||||
|
|
@ -218,6 +218,10 @@ void EditorRunBar::_run_scene(const String &p_scene_path, const Vector<String> &
|
|||
return;
|
||||
}
|
||||
|
||||
if (!EditorNode::get_singleton()->validate_custom_directory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_reset_play_buttons();
|
||||
|
||||
String write_movie_file;
|
||||
|
|
@ -255,7 +259,7 @@ void EditorRunBar::_run_scene(const String &p_scene_path, const Vector<String> &
|
|||
String run_filename;
|
||||
switch (current_mode) {
|
||||
case RUN_CUSTOM: {
|
||||
run_filename = p_scene_path;
|
||||
run_filename = ResourceUID::ensure_path(p_scene_path);
|
||||
run_custom_filename = run_filename;
|
||||
} break;
|
||||
|
||||
|
|
@ -530,6 +534,7 @@ EditorRunBar::EditorRunBar() {
|
|||
recovery_mode_reload_button->set_theme_type_variation("RunBarButton");
|
||||
recovery_mode_reload_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
recovery_mode_reload_button->set_tooltip_text(TTR("Disable recovery mode and reload the project."));
|
||||
recovery_mode_reload_button->set_accessibility_name(TTRC("Disable Recovery Mode"));
|
||||
recovery_mode_reload_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::recovery_mode_reload_project));
|
||||
|
||||
recovery_mode_panel = memnew(PanelContainer);
|
||||
|
|
@ -552,6 +557,7 @@ EditorRunBar::EditorRunBar() {
|
|||
play_button->set_toggle_mode(true);
|
||||
play_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
play_button->set_tooltip_text(TTRC("Run the project's default scene."));
|
||||
play_button->set_accessibility_name(TTRC("Run Default Scene"));
|
||||
play_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::play_main_scene).bind(false));
|
||||
|
||||
ED_SHORTCUT_AND_COMMAND("editor/run_project", TTRC("Run Project"), Key::F5);
|
||||
|
|
@ -564,6 +570,7 @@ EditorRunBar::EditorRunBar() {
|
|||
pause_button->set_toggle_mode(true);
|
||||
pause_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
pause_button->set_tooltip_text(TTRC("Pause the running project's execution for debugging."));
|
||||
pause_button->set_accessibility_name(TTRC("Pause"));
|
||||
pause_button->set_disabled(true);
|
||||
|
||||
ED_SHORTCUT("editor/pause_running_project", TTRC("Pause Running Project"), Key::F7);
|
||||
|
|
@ -575,6 +582,7 @@ EditorRunBar::EditorRunBar() {
|
|||
stop_button->set_theme_type_variation("RunBarButton");
|
||||
stop_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
stop_button->set_tooltip_text(TTRC("Stop the currently running project."));
|
||||
stop_button->set_accessibility_name(TTRC("Stop"));
|
||||
stop_button->set_disabled(true);
|
||||
stop_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::stop_playing));
|
||||
|
||||
|
|
@ -587,7 +595,7 @@ EditorRunBar::EditorRunBar() {
|
|||
run_native->connect("native_run", callable_mp(this, &EditorRunBar::_run_native));
|
||||
|
||||
bool add_play_xr_mode_options = false;
|
||||
#ifndef _3D_DISABLED
|
||||
#ifndef XR_DISABLED
|
||||
if (OS::get_singleton()->has_feature("xr_editor") &&
|
||||
(XRServer::get_xr_mode() == XRServer::XRMODE_ON ||
|
||||
(XRServer::get_xr_mode() == XRServer::XRMODE_DEFAULT && GLOBAL_GET("xr/openxr/enabled")))) {
|
||||
|
|
@ -596,7 +604,7 @@ EditorRunBar::EditorRunBar() {
|
|||
// either regular mode or XR mode.
|
||||
add_play_xr_mode_options = true;
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
#endif // XR_DISABLED
|
||||
|
||||
if (add_play_xr_mode_options) {
|
||||
MenuButton *menu_button = memnew(MenuButton);
|
||||
|
|
@ -614,6 +622,7 @@ EditorRunBar::EditorRunBar() {
|
|||
play_scene_button->set_theme_type_variation("RunBarButton");
|
||||
play_scene_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
play_scene_button->set_tooltip_text(TTRC("Run the currently edited scene."));
|
||||
play_scene_button->set_accessibility_name(TTRC("Run Edited Scene"));
|
||||
|
||||
ED_SHORTCUT_AND_COMMAND("editor/run_current_scene", TTRC("Run Current Scene"), Key::F6);
|
||||
ED_SHORTCUT_OVERRIDE("editor/run_current_scene", "macos", KeyModifierMask::META | Key::R);
|
||||
|
|
@ -635,6 +644,7 @@ EditorRunBar::EditorRunBar() {
|
|||
play_custom_scene_button->set_theme_type_variation("RunBarButton");
|
||||
play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
play_custom_scene_button->set_tooltip_text(TTRC("Run a specific scene."));
|
||||
play_custom_scene_button->set_accessibility_name(TTRC("Run Specific Scene"));
|
||||
|
||||
ED_SHORTCUT_AND_COMMAND("editor/run_specific_scene", TTRC("Run Specific Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5);
|
||||
ED_SHORTCUT_OVERRIDE("editor/run_specific_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R);
|
||||
|
|
@ -650,5 +660,6 @@ EditorRunBar::EditorRunBar() {
|
|||
write_movie_button->set_pressed(false);
|
||||
write_movie_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
write_movie_button->set_tooltip_text(TTR("Enable Movie Maker mode.\nThe project will run at stable FPS and the visual and audio output will be recorded to a video file."));
|
||||
write_movie_button->set_accessibility_name(TTRC("Enable Movie Maker Mode"));
|
||||
write_movie_button->connect(SceneStringName(toggled), callable_mp(this, &EditorRunBar::_write_movie_toggled));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_RUN_BAR_H
|
||||
#define EDITOR_RUN_BAR_H
|
||||
#pragma once
|
||||
|
||||
#include "editor/editor_run.h"
|
||||
#include "editor/export/editor_export.h"
|
||||
|
|
@ -132,5 +131,3 @@ public:
|
|||
|
||||
EditorRunBar();
|
||||
};
|
||||
|
||||
#endif // EDITOR_RUN_BAR_H
|
||||
|
|
|
|||
|
|
@ -67,6 +67,11 @@ void EditorSceneTabs::_notification(int p_what) {
|
|||
_scene_tabs_resized();
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
_scene_tabs_resized();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -116,15 +121,10 @@ void EditorSceneTabs::_scene_tab_exit() {
|
|||
}
|
||||
|
||||
void EditorSceneTabs::_scene_tab_input(const Ref<InputEvent> &p_input) {
|
||||
int tab_id = scene_tabs->get_hovered_tab();
|
||||
Ref<InputEventMouseButton> mb = p_input;
|
||||
|
||||
if (mb.is_valid()) {
|
||||
if (tab_id >= 0) {
|
||||
if (mb->get_button_index() == MouseButton::MIDDLE && mb->is_pressed()) {
|
||||
_scene_tab_closed(tab_id);
|
||||
}
|
||||
} else if (mb->get_button_index() == MouseButton::LEFT && mb->is_double_click()) {
|
||||
if (mb->get_button_index() == MouseButton::LEFT && mb->is_double_click()) {
|
||||
int tab_buttons = 0;
|
||||
if (scene_tabs->get_offset_buttons_visible()) {
|
||||
tab_buttons = get_theme_icon(SNAME("increment"), SNAME("TabBar"))->get_width() + get_theme_icon(SNAME("decrement"), SNAME("TabBar"))->get_width();
|
||||
|
|
@ -203,7 +203,7 @@ void EditorSceneTabs::_update_context_menu() {
|
|||
scene_tabs_context_menu->set_item_text(-1, TTR("Close Tab"));
|
||||
scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/reopen_closed_scene"), EditorNode::FILE_OPEN_PREV);
|
||||
scene_tabs_context_menu->set_item_text(-1, TTR("Undo Close Tab"));
|
||||
DISABLE_LAST_OPTION_IF(!EditorNode::get_singleton()->has_previous_scenes());
|
||||
DISABLE_LAST_OPTION_IF(!EditorNode::get_singleton()->has_previous_closed_scenes());
|
||||
scene_tabs_context_menu->add_item(TTR("Close Other Tabs"), SCENE_CLOSE_OTHERS);
|
||||
DISABLE_LAST_OPTION_IF(EditorNode::get_editor_data().get_edited_scene_count() <= 1);
|
||||
scene_tabs_context_menu->add_item(TTR("Close Tabs to the Right"), SCENE_CLOSE_RIGHT);
|
||||
|
|
@ -437,6 +437,7 @@ EditorSceneTabs::EditorSceneTabs() {
|
|||
scene_tab_add = memnew(Button);
|
||||
scene_tab_add->set_flat(true);
|
||||
scene_tab_add->set_tooltip_text(TTR("Add a new scene."));
|
||||
scene_tab_add->set_accessibility_name(TTRC("Add Scene"));
|
||||
scene_tabs->add_child(scene_tab_add);
|
||||
scene_tab_add->connect(SceneStringName(pressed), callable_mp(EditorNode::get_singleton(), &EditorNode::trigger_menu_option).bind(EditorNode::FILE_NEW_SCENE, false));
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_SCENE_TABS_H
|
||||
#define EDITOR_SCENE_TABS_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/margin_container.h"
|
||||
|
||||
|
|
@ -106,5 +105,3 @@ public:
|
|||
|
||||
EditorSceneTabs();
|
||||
};
|
||||
|
||||
#endif // EDITOR_SCENE_TABS_H
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
|
|||
}
|
||||
grabbing_spinner_dist_cache += diff_x * grabbing_spinner_speed;
|
||||
|
||||
if (!grabbing_spinner && ABS(grabbing_spinner_dist_cache) > 4 * grabbing_spinner_speed * EDSCALE) {
|
||||
if (!grabbing_spinner && Math::abs(grabbing_spinner_dist_cache) > 4 * grabbing_spinner_speed * EDSCALE) {
|
||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
|
||||
grabbing_spinner = true;
|
||||
}
|
||||
|
|
@ -187,9 +187,11 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
|
|||
if (mb->get_button_index() == MouseButton::WHEEL_UP) {
|
||||
set_value(get_value() + get_step());
|
||||
mousewheel_over_grabber = true;
|
||||
accept_event();
|
||||
} else if (mb->get_button_index() == MouseButton::WHEEL_DOWN) {
|
||||
set_value(get_value() - get_step());
|
||||
mousewheel_over_grabber = true;
|
||||
accept_event();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -435,13 +437,11 @@ void EditorSpinSlider::_draw_spin_slider() {
|
|||
grabber->set_texture(grabber_tex);
|
||||
}
|
||||
|
||||
Vector2 scale = get_global_transform_with_canvas().get_scale();
|
||||
grabber->set_scale(scale);
|
||||
grabber->reset_size();
|
||||
grabber->set_position((grabber_rect.get_center() - grabber->get_size() * 0.5) * scale);
|
||||
grabber->set_position(grabber_rect.get_center() - grabber->get_size() * 0.5);
|
||||
|
||||
if (mousewheel_over_grabber) {
|
||||
Input::get_singleton()->warp_mouse(grabber->get_position() + grabber_rect.size);
|
||||
Input::get_singleton()->warp_mouse(grabber->get_global_position() + grabber_rect.size);
|
||||
}
|
||||
|
||||
grabber_range = width;
|
||||
|
|
@ -457,6 +457,8 @@ void EditorSpinSlider::_notification(int p_what) {
|
|||
_update_value_input_stylebox();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
||||
case NOTIFICATION_TRANSLATION_CHANGED:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
_update_value_input_stylebox();
|
||||
} break;
|
||||
|
|
@ -566,8 +568,8 @@ void EditorSpinSlider::_evaluate_input_text() {
|
|||
expr.instantiate();
|
||||
|
||||
// Convert commas ',' to dots '.' for French/German etc. keyboard layouts.
|
||||
String text = value_input->get_text().replace(",", ".");
|
||||
text = text.replace(";", ",");
|
||||
String text = value_input->get_text().replace_char(',', '.');
|
||||
text = text.replace_char(';', ',');
|
||||
text = TS->parse_number(text);
|
||||
|
||||
Error err = expr->parse(text);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_SPIN_SLIDER_H
|
||||
#define EDITOR_SPIN_SLIDER_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/range.h"
|
||||
|
|
@ -131,5 +130,3 @@ public:
|
|||
virtual Size2 get_minimum_size() const override;
|
||||
EditorSpinSlider();
|
||||
};
|
||||
|
||||
#endif // EDITOR_SPIN_SLIDER_H
|
||||
|
|
|
|||
|
|
@ -80,6 +80,53 @@ void EditorTitleBar::gui_input(const Ref<InputEvent> &p_event) {
|
|||
}
|
||||
}
|
||||
|
||||
void EditorTitleBar::set_center_control(Control *p_center_control) {
|
||||
center_control = p_center_control;
|
||||
}
|
||||
|
||||
Control *EditorTitleBar::get_center_control() const {
|
||||
return center_control;
|
||||
}
|
||||
|
||||
void EditorTitleBar::_notification(int p_what) {
|
||||
if (!center_control || p_what != NOTIFICATION_SORT_CHILDREN) {
|
||||
return;
|
||||
}
|
||||
|
||||
Control *prev = nullptr;
|
||||
Control *base = nullptr;
|
||||
Control *next = nullptr;
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = as_sortable_control(get_child(i));
|
||||
if (!c) {
|
||||
continue;
|
||||
}
|
||||
if (base) {
|
||||
next = c;
|
||||
break;
|
||||
}
|
||||
if (c != center_control) {
|
||||
prev = c;
|
||||
continue;
|
||||
}
|
||||
base = c;
|
||||
}
|
||||
if (base && prev && next) {
|
||||
Size2i title_size = get_size();
|
||||
Size2i c_size = base->get_combined_minimum_size();
|
||||
|
||||
int min_offset = prev->get_position().x + prev->get_combined_minimum_size().x;
|
||||
int max_offset = next->get_position().x + next->get_size().x - next->get_combined_minimum_size().x - c_size.x;
|
||||
|
||||
int offset = (title_size.width - c_size.width) / 2;
|
||||
offset = CLAMP(offset, min_offset, max_offset);
|
||||
|
||||
fit_child_in_rect(prev, Rect2i(prev->get_position().x, 0, offset - prev->get_position().x, title_size.height));
|
||||
fit_child_in_rect(base, Rect2i(offset, 0, c_size.width, title_size.height));
|
||||
fit_child_in_rect(next, Rect2i(offset + c_size.width, 0, next->get_position().x + next->get_size().x - (offset + c_size.width), title_size.height));
|
||||
}
|
||||
}
|
||||
|
||||
void EditorTitleBar::set_can_move_window(bool p_enabled) {
|
||||
can_move = p_enabled;
|
||||
set_process_input(can_move);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_TITLE_BAR_H
|
||||
#define EDITOR_TITLE_BAR_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/main/window.h"
|
||||
|
|
@ -40,14 +39,18 @@ class EditorTitleBar : public HBoxContainer {
|
|||
Point2i click_pos;
|
||||
bool moving = false;
|
||||
bool can_move = false;
|
||||
Control *center_control = nullptr;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||
static void _bind_methods() {}
|
||||
|
||||
public:
|
||||
void set_center_control(Control *p_center_control);
|
||||
Control *get_center_control() const;
|
||||
|
||||
void set_can_move_window(bool p_enabled);
|
||||
bool get_can_move_window() const;
|
||||
};
|
||||
|
||||
#endif // EDITOR_TITLE_BAR_H
|
||||
|
|
|
|||
|
|
@ -374,11 +374,13 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_
|
|||
// Add buttons.
|
||||
if (p_time > 0.0) {
|
||||
Button *copy_button = memnew(Button);
|
||||
copy_button->set_accessibility_name(TTRC("Copy"));
|
||||
copy_button->set_flat(true);
|
||||
copy_button->connect(SceneStringName(pressed), callable_mp(this, &EditorToaster::copy).bind(panel));
|
||||
hbox_container->add_child(copy_button);
|
||||
|
||||
Button *close_button = memnew(Button);
|
||||
close_button->set_accessibility_name(TTRC("Close"));
|
||||
close_button->set_flat(true);
|
||||
close_button->connect(SceneStringName(pressed), callable_mp(this, &EditorToaster::instant_close).bind(panel));
|
||||
hbox_container->add_child(close_button);
|
||||
|
|
@ -572,6 +574,7 @@ EditorToaster::EditorToaster() {
|
|||
|
||||
// Main button.
|
||||
main_button = memnew(Button);
|
||||
main_button->set_accessibility_name(TTRC("Notifications"));
|
||||
main_button->set_tooltip_text(TTR("No notifications."));
|
||||
main_button->set_modulate(Color(0.5, 0.5, 0.5));
|
||||
main_button->set_disabled(true);
|
||||
|
|
@ -588,6 +591,7 @@ EditorToaster::EditorToaster() {
|
|||
add_child(disable_notifications_panel);
|
||||
|
||||
disable_notifications_button = memnew(Button);
|
||||
disable_notifications_button->set_accessibility_name(TTRC("Silence Notifications"));
|
||||
disable_notifications_button->set_tooltip_text(TTR("Silence the notifications."));
|
||||
disable_notifications_button->set_flat(true);
|
||||
disable_notifications_button->connect(SceneStringName(pressed), callable_mp(this, &EditorToaster::_set_notifications_enabled).bind(false));
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_TOASTER_H
|
||||
#define EDITOR_TOASTER_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
|
||||
|
|
@ -125,5 +124,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(EditorToaster::Severity);
|
||||
|
||||
#endif // EDITOR_TOASTER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_VALIDATION_PANEL_H
|
||||
#define EDITOR_VALIDATION_PANEL_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/panel_container.h"
|
||||
|
||||
|
|
@ -84,5 +83,3 @@ public:
|
|||
|
||||
EditorValidationPanel();
|
||||
};
|
||||
|
||||
#endif // EDITOR_VALIDATION_PANEL_H
|
||||
|
|
|
|||
|
|
@ -37,20 +37,20 @@ String _get_version_string(EditorVersionButton::VersionFormat p_format) {
|
|||
String main;
|
||||
switch (p_format) {
|
||||
case EditorVersionButton::FORMAT_BASIC: {
|
||||
return VERSION_FULL_CONFIG;
|
||||
return GODOT_VERSION_FULL_CONFIG;
|
||||
} break;
|
||||
case EditorVersionButton::FORMAT_WITH_BUILD: {
|
||||
main = "v" VERSION_FULL_BUILD;
|
||||
main = "v" GODOT_VERSION_FULL_BUILD;
|
||||
} break;
|
||||
case EditorVersionButton::FORMAT_WITH_NAME_AND_BUILD: {
|
||||
main = VERSION_FULL_NAME;
|
||||
main = GODOT_VERSION_FULL_NAME;
|
||||
} break;
|
||||
default: {
|
||||
ERR_FAIL_V_MSG(VERSION_FULL_NAME, "Unexpected format: " + itos(p_format));
|
||||
ERR_FAIL_V_MSG(GODOT_VERSION_FULL_NAME, "Unexpected format: " + itos(p_format));
|
||||
} break;
|
||||
}
|
||||
|
||||
String hash = VERSION_HASH;
|
||||
String hash = GODOT_VERSION_HASH;
|
||||
if (!hash.is_empty()) {
|
||||
hash = vformat(" [%s]", hash.left(9));
|
||||
}
|
||||
|
|
@ -76,8 +76,8 @@ EditorVersionButton::EditorVersionButton(VersionFormat p_format) {
|
|||
set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
|
||||
|
||||
String build_date;
|
||||
if (VERSION_TIMESTAMP > 0) {
|
||||
build_date = Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC";
|
||||
if (GODOT_VERSION_TIMESTAMP > 0) {
|
||||
build_date = Time::get_singleton()->get_datetime_string_from_unix_time(GODOT_VERSION_TIMESTAMP, true) + " UTC";
|
||||
} else {
|
||||
build_date = TTR("(unknown)");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_VERSION_BUTTON_H
|
||||
#define EDITOR_VERSION_BUTTON_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/link_button.h"
|
||||
|
||||
|
|
@ -57,5 +56,3 @@ protected:
|
|||
public:
|
||||
EditorVersionButton(VersionFormat p_format);
|
||||
};
|
||||
|
||||
#endif // EDITOR_VERSION_BUTTON_H
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ void EditorZoomWidget::set_shortcut_context(Node *p_node) const {
|
|||
EditorZoomWidget::EditorZoomWidget() {
|
||||
// Zoom buttons
|
||||
zoom_minus = memnew(Button);
|
||||
zoom_minus->set_accessibility_name(TTRC("Zoom Out"));
|
||||
zoom_minus->set_flat(true);
|
||||
zoom_minus->set_shortcut(ED_SHORTCUT_ARRAY("canvas_item_editor/zoom_minus", TTRC("Zoom Out"), { int32_t(KeyModifierMask::CMD_OR_CTRL | Key::MINUS), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_SUBTRACT) }));
|
||||
zoom_minus->set_shortcut_context(this);
|
||||
|
|
@ -196,6 +197,7 @@ EditorZoomWidget::EditorZoomWidget() {
|
|||
|
||||
zoom_reset = memnew(Button);
|
||||
zoom_reset->set_flat(true);
|
||||
zoom_reset->set_accessibility_name(TTRC("Reset Zoom"));
|
||||
|
||||
Ref<StyleBoxEmpty> empty_stylebox = memnew(StyleBoxEmpty);
|
||||
zoom_reset->add_theme_style_override(CoreStringName(normal), empty_stylebox);
|
||||
|
|
@ -216,6 +218,7 @@ EditorZoomWidget::EditorZoomWidget() {
|
|||
zoom_reset->connect(SceneStringName(pressed), callable_mp(this, &EditorZoomWidget::_button_zoom_reset));
|
||||
|
||||
zoom_plus = memnew(Button);
|
||||
zoom_plus->set_accessibility_name(TTRC("Zoom In"));
|
||||
zoom_plus->set_flat(true);
|
||||
zoom_plus->set_shortcut(ED_SHORTCUT_ARRAY("canvas_item_editor/zoom_plus", TTRC("Zoom In"), { int32_t(KeyModifierMask::CMD_OR_CTRL | Key::EQUAL), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_ADD) }));
|
||||
zoom_plus->set_shortcut_context(this);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EDITOR_ZOOM_WIDGET_H
|
||||
#define EDITOR_ZOOM_WIDGET_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
|
|
@ -67,5 +66,3 @@ public:
|
|||
// Sets the shortcut context for the zoom buttons. By default their context is this EditorZoomWidget control.
|
||||
void set_shortcut_context(Node *p_node) const;
|
||||
};
|
||||
|
||||
#endif // EDITOR_ZOOM_WIDGET_H
|
||||
|
|
|
|||
|
|
@ -63,13 +63,13 @@ PackedStringArray SceneTreeEditor::_get_node_configuration_warnings(Node *p_node
|
|||
if (node_2d) {
|
||||
// Note: Warn for Node2D but not all CanvasItems, don't warn for Control nodes.
|
||||
// Control nodes may have reasons to use a transformed root node like anchors.
|
||||
if (!node_2d->get_transform().is_equal_approx(Transform2D())) {
|
||||
if (!node_2d->get_position().is_zero_approx()) {
|
||||
warnings.append(TTR("The root node of a scene is recommended to not be transformed, since instances of the scene will usually override this. Reset the transform and reload the scene to remove this warning."));
|
||||
}
|
||||
}
|
||||
Node3D *node_3d = Object::cast_to<Node3D>(p_node);
|
||||
if (node_3d) {
|
||||
if (!node_3d->get_transform().is_equal_approx(Transform3D())) {
|
||||
if (!node_3d->get_position().is_zero_approx()) {
|
||||
warnings.append(TTR("The root node of a scene is recommended to not be transformed, since instances of the scene will usually override this. Reset the transform and reload the scene to remove this warning."));
|
||||
}
|
||||
}
|
||||
|
|
@ -77,6 +77,12 @@ PackedStringArray SceneTreeEditor::_get_node_configuration_warnings(Node *p_node
|
|||
return warnings;
|
||||
}
|
||||
|
||||
PackedStringArray SceneTreeEditor::_get_node_accessibility_configuration_warnings(Node *p_node) {
|
||||
PackedStringArray warnings = p_node->get_accessibility_configuration_warnings();
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
||||
void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button) {
|
||||
if (p_button != MouseButton::LEFT) {
|
||||
return;
|
||||
|
|
@ -112,7 +118,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
|
|||
} else if (p_id == BUTTON_VISIBILITY) {
|
||||
undo_redo->create_action(TTR("Toggle Visible"));
|
||||
_toggle_visible(n);
|
||||
List<Node *> selection = editor_selection->get_selected_node_list();
|
||||
List<Node *> selection = editor_selection->get_top_selected_node_list();
|
||||
if (selection.size() > 1 && selection.find(n) != nullptr) {
|
||||
for (Node *nv : selection) {
|
||||
ERR_FAIL_NULL(nv);
|
||||
|
|
@ -151,8 +157,10 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
|
|||
}
|
||||
undo_redo->commit_action();
|
||||
} else if (p_id == BUTTON_WARNING) {
|
||||
const PackedStringArray warnings = _get_node_configuration_warnings(n);
|
||||
|
||||
PackedStringArray warnings = _get_node_configuration_warnings(n);
|
||||
if (accessibility_warnings) {
|
||||
warnings.append_array(_get_node_accessibility_configuration_warnings(n));
|
||||
}
|
||||
if (warnings.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -447,7 +455,7 @@ void SceneTreeEditor::_update_node(Node *p_node, TreeItem *p_item, bool p_part_o
|
|||
_set_item_custom_color(p_item, accent);
|
||||
}
|
||||
} else if (p_part_of_subscene) {
|
||||
if (valid_types.size() == 0) {
|
||||
if (valid_types.is_empty()) {
|
||||
_set_item_custom_color(p_item, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
|
||||
}
|
||||
} else if (marked.has(p_node)) {
|
||||
|
|
@ -473,7 +481,11 @@ void SceneTreeEditor::_update_node(Node *p_node, TreeItem *p_item, bool p_part_o
|
|||
}
|
||||
|
||||
if (can_rename) { // TODO Should be can edit..
|
||||
const PackedStringArray warnings = _get_node_configuration_warnings(p_node);
|
||||
PackedStringArray warnings = _get_node_configuration_warnings(p_node);
|
||||
if (accessibility_warnings) {
|
||||
warnings.append_array(_get_node_accessibility_configuration_warnings(p_node));
|
||||
}
|
||||
|
||||
const int num_warnings = warnings.size();
|
||||
if (num_warnings > 0) {
|
||||
StringName warning_icon;
|
||||
|
|
@ -512,8 +524,7 @@ void SceneTreeEditor::_update_node(Node *p_node, TreeItem *p_item, bool p_part_o
|
|||
|
||||
String msg_temp;
|
||||
if (num_connections >= 1) {
|
||||
Array arr;
|
||||
arr.push_back(num_connections);
|
||||
Array arr = { num_connections };
|
||||
msg_temp += TTRN("Node has one connection.", "Node has {num} connections.", num_connections).format(arr, "{num}");
|
||||
if (num_groups >= 1) {
|
||||
msg_temp += "\n";
|
||||
|
|
@ -1291,7 +1302,7 @@ void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_
|
|||
|
||||
void SceneTreeEditor::_tree_scroll_to_item(ObjectID p_item_id) {
|
||||
ERR_FAIL_NULL(tree);
|
||||
TreeItem *item = Object::cast_to<TreeItem>(ObjectDB::get_instance(p_item_id));
|
||||
TreeItem *item = ObjectDB::get_instance<TreeItem>(p_item_id);
|
||||
if (item) {
|
||||
tree->scroll_to_item(item, true);
|
||||
}
|
||||
|
|
@ -1840,7 +1851,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
|
|||
}
|
||||
|
||||
bool SceneTreeEditor::_is_script_type(const StringName &p_type) const {
|
||||
return (script_types->find(p_type));
|
||||
return (script_types->has(p_type));
|
||||
}
|
||||
|
||||
bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
|
||||
|
|
@ -1853,12 +1864,12 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
|
|||
return false;
|
||||
}
|
||||
|
||||
TreeItem *item = tree->get_item_at_position(p_point);
|
||||
TreeItem *item = (p_point == Vector2(Math::INF, Math::INF)) ? tree->get_selected() : tree->get_item_at_position(p_point);
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int section = tree->get_drop_section_at_position(p_point);
|
||||
int section = (p_point == Vector2(Math::INF, Math::INF)) ? tree->get_drop_section_at_position(tree->get_item_rect(item).position) : tree->get_drop_section_at_position(p_point);
|
||||
if (section < -1 || (section == -1 && !item->get_parent())) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1866,7 +1877,7 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
|
|||
if (String(d["type"]) == "files") {
|
||||
Vector<String> files = d["files"];
|
||||
|
||||
if (files.size() == 0) {
|
||||
if (files.is_empty()) {
|
||||
return false; // TODO Weird?
|
||||
}
|
||||
|
||||
|
|
@ -1942,11 +1953,11 @@ void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data,
|
|||
return;
|
||||
}
|
||||
|
||||
TreeItem *item = tree->get_item_at_position(p_point);
|
||||
TreeItem *item = (p_point == Vector2(Math::INF, Math::INF)) ? tree->get_selected() : tree->get_item_at_position(p_point);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
int section = tree->get_drop_section_at_position(p_point);
|
||||
int section = (p_point == Vector2(Math::INF, Math::INF)) ? tree->get_drop_section_at_position(tree->get_item_rect(item).position) : tree->get_drop_section_at_position(p_point);
|
||||
if (section < -1) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -2036,6 +2047,13 @@ void SceneTreeEditor::set_hide_filtered_out_parents(bool p_hide, bool p_update_s
|
|||
}
|
||||
}
|
||||
|
||||
void SceneTreeEditor::set_accessibility_warnings(bool p_enable, bool p_update_settings) {
|
||||
if (p_update_settings) {
|
||||
EditorSettings::get_singleton()->set("docks/scene_tree/accessibility_warnings", p_enable);
|
||||
}
|
||||
accessibility_warnings = p_enable;
|
||||
}
|
||||
|
||||
void SceneTreeEditor::set_connect_to_script_mode(bool p_enable) {
|
||||
connect_to_script_mode = p_enable;
|
||||
_update_tree();
|
||||
|
|
@ -2145,8 +2163,8 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
|
|||
ask_before_revoke_checkbox->set_tooltip_text(TTR("This dialog can also be enabled/disabled in the Editor Settings: Docks > Scene Tree > Ask Before Revoking Unique Name."));
|
||||
vb->add_child(ask_before_revoke_checkbox);
|
||||
|
||||
script_types = memnew(List<StringName>);
|
||||
ClassDB::get_inheriters_from_class("Script", script_types);
|
||||
script_types = memnew(LocalVector<StringName>);
|
||||
ClassDB::get_inheriters_from_class("Script", *script_types);
|
||||
}
|
||||
|
||||
SceneTreeEditor::~SceneTreeEditor() {
|
||||
|
|
@ -2341,9 +2359,6 @@ SceneTreeDialog::SceneTreeDialog() {
|
|||
tree->connect("node_selected", callable_mp(this, &SceneTreeDialog::_selected_changed));
|
||||
}
|
||||
|
||||
SceneTreeDialog::~SceneTreeDialog() {
|
||||
}
|
||||
|
||||
/******** CACHE *********/
|
||||
|
||||
HashMap<Node *, SceneTreeEditor::CachedNode>::Iterator SceneTreeEditor::NodeCache::add(Node *p_node, TreeItem *p_item) {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef SCENE_TREE_EDITOR_H
|
||||
#define SCENE_TREE_EDITOR_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/check_box.h"
|
||||
#include "scene/gui/check_button.h"
|
||||
|
|
@ -128,6 +127,7 @@ class SceneTreeEditor : public Control {
|
|||
|
||||
bool auto_expand_selected = true;
|
||||
bool hide_filtered_out_parents = false;
|
||||
bool accessibility_warnings = false;
|
||||
bool connect_to_script_mode = false;
|
||||
bool connecting_signal = false;
|
||||
bool update_when_invisible = true;
|
||||
|
|
@ -137,6 +137,7 @@ class SceneTreeEditor : public Control {
|
|||
void _compute_hash(Node *p_node, uint64_t &hash);
|
||||
void _reset();
|
||||
PackedStringArray _get_node_configuration_warnings(Node *p_node);
|
||||
PackedStringArray _get_node_accessibility_configuration_warnings(Node *p_node);
|
||||
|
||||
void _update_node_path(Node *p_node, bool p_recursive = true);
|
||||
void _update_node_subtree(Node *p_node, TreeItem *p_parent, bool p_force = false);
|
||||
|
|
@ -213,7 +214,7 @@ class SceneTreeEditor : public Control {
|
|||
|
||||
Timer *update_timer = nullptr;
|
||||
|
||||
List<StringName> *script_types;
|
||||
LocalVector<StringName> *script_types;
|
||||
bool _is_script_type(const StringName &p_type) const;
|
||||
|
||||
Vector<StringName> valid_types;
|
||||
|
|
@ -249,6 +250,7 @@ public:
|
|||
|
||||
void set_auto_expand_selected(bool p_auto, bool p_update_settings);
|
||||
void set_hide_filtered_out_parents(bool p_hide, bool p_update_settings);
|
||||
void set_accessibility_warnings(bool p_enable, bool p_update_settings);
|
||||
void set_connect_to_script_mode(bool p_enable);
|
||||
void set_connecting_signal(bool p_enable);
|
||||
void set_update_when_invisible(bool p_enable);
|
||||
|
|
@ -291,7 +293,4 @@ public:
|
|||
LineEdit *get_filter_line_edit() { return filter; }
|
||||
|
||||
SceneTreeDialog();
|
||||
~SceneTreeDialog();
|
||||
};
|
||||
|
||||
#endif // SCENE_TREE_EDITOR_H
|
||||
|
|
|
|||
184
engine/editor/gui/touch_actions_panel.cpp
Normal file
184
engine/editor/gui/touch_actions_panel.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/**************************************************************************/
|
||||
/* touch_actions_panel.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "touch_actions_panel.h"
|
||||
|
||||
#include "core/input/input.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/editor_string_names.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/color_rect.h"
|
||||
#include "scene/gui/texture_rect.h"
|
||||
#include "scene/resources/style_box_flat.h"
|
||||
|
||||
void TouchActionsPanel::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
DisplayServer::get_singleton()->set_hardware_keyboard_connection_change_callback(callable_mp(this, &TouchActionsPanel::_hardware_keyboard_connected));
|
||||
_hardware_keyboard_connected(DisplayServer::get_singleton()->has_hardware_keyboard());
|
||||
} break;
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
drag_handle->set_texture(get_editor_theme_icon(SNAME("DragHandle")));
|
||||
layout_toggle_button->set_button_icon(get_editor_theme_icon(SNAME("Orientation")));
|
||||
lock_panel_button->set_button_icon(get_editor_theme_icon(SNAME("Lock")));
|
||||
save_button->set_button_icon(get_editor_theme_icon(SNAME("Save")));
|
||||
delete_button->set_button_icon(get_editor_theme_icon(SNAME("Remove")));
|
||||
undo_button->set_button_icon(get_editor_theme_icon(SNAME("UndoRedo")));
|
||||
redo_button->set_button_icon(get_editor_theme_icon(SNAME("Redo")));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void TouchActionsPanel::_hardware_keyboard_connected(bool p_connected) {
|
||||
set_visible(!p_connected);
|
||||
}
|
||||
|
||||
void TouchActionsPanel::_simulate_editor_shortcut(const String &p_shortcut_name) {
|
||||
Ref<Shortcut> shortcut = ED_GET_SHORTCUT(p_shortcut_name);
|
||||
|
||||
if (shortcut.is_valid() && !shortcut->get_events().is_empty()) {
|
||||
Ref<InputEventKey> event = shortcut->get_events()[0];
|
||||
if (event.is_valid()) {
|
||||
event->set_pressed(true);
|
||||
Input::get_singleton()->parse_input_event(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TouchActionsPanel::_simulate_key_press(Key p_keycode) {
|
||||
Ref<InputEventKey> event;
|
||||
event.instantiate();
|
||||
event->set_keycode(p_keycode);
|
||||
event->set_pressed(true);
|
||||
Input::get_singleton()->parse_input_event(event);
|
||||
}
|
||||
|
||||
Button *TouchActionsPanel::_add_new_action_button(const String &p_shortcut, const String &p_name, Key p_keycode) {
|
||||
Button *action_button = memnew(Button);
|
||||
action_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
action_button->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||
action_button->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||
action_button->set_accessibility_name(p_name);
|
||||
if (p_keycode == Key::NONE) {
|
||||
action_button->connect(SceneStringName(pressed), callable_mp(this, &TouchActionsPanel::_simulate_editor_shortcut).bind(p_shortcut));
|
||||
} else {
|
||||
action_button->connect(SceneStringName(pressed), callable_mp(this, &TouchActionsPanel::_simulate_key_press).bind(p_keycode));
|
||||
}
|
||||
box->add_child(action_button);
|
||||
return action_button;
|
||||
}
|
||||
|
||||
void TouchActionsPanel::_on_drag_handle_gui_input(const Ref<InputEvent> &p_event) {
|
||||
if (lock_panel_position) {
|
||||
return;
|
||||
}
|
||||
Ref<InputEventMouseButton> mouse_button_event = p_event;
|
||||
if (mouse_button_event.is_valid() && mouse_button_event->get_button_index() == MouseButton::LEFT) {
|
||||
if (mouse_button_event->is_pressed()) {
|
||||
dragging = true;
|
||||
drag_offset = mouse_button_event->get_position();
|
||||
} else {
|
||||
dragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
Ref<InputEventMouseMotion> mouse_motion_event = p_event;
|
||||
if (dragging && mouse_motion_event.is_valid()) {
|
||||
Vector2 new_position = get_position() + mouse_motion_event->get_relative();
|
||||
const float margin = 25.0;
|
||||
Vector2 parent_size = get_parent_area_size();
|
||||
Vector2 panel_size = get_size();
|
||||
new_position = new_position.clamp(Vector2(margin, margin), parent_size - panel_size - Vector2(margin, margin));
|
||||
set_position(new_position);
|
||||
}
|
||||
}
|
||||
|
||||
void TouchActionsPanel::_switch_layout() {
|
||||
box->set_vertical(!box->is_vertical());
|
||||
reset_size();
|
||||
}
|
||||
|
||||
void TouchActionsPanel::_lock_panel_toggled(bool p_pressed) {
|
||||
lock_panel_position = p_pressed;
|
||||
layout_toggle_button->set_disabled(p_pressed);
|
||||
}
|
||||
|
||||
TouchActionsPanel::TouchActionsPanel() {
|
||||
Ref<StyleBoxFlat> panel_style;
|
||||
panel_style.instantiate();
|
||||
panel_style->set_bg_color(Color(0.1, 0.1, 0.1, 1));
|
||||
panel_style->set_border_color(Color(0.3, 0.3, 0.3, 1));
|
||||
panel_style->set_border_width_all(3);
|
||||
panel_style->set_corner_radius_all(10);
|
||||
panel_style->set_content_margin_all(12);
|
||||
add_theme_style_override(SceneStringName(panel), panel_style);
|
||||
|
||||
set_anchors_and_offsets_preset(Control::PRESET_CENTER_BOTTOM, Control::PRESET_MODE_MINSIZE, 80);
|
||||
|
||||
box = memnew(BoxContainer);
|
||||
box->set_alignment(BoxContainer::ALIGNMENT_CENTER);
|
||||
box->add_theme_constant_override("separation", 15);
|
||||
add_child(box);
|
||||
|
||||
drag_handle = memnew(TextureRect);
|
||||
drag_handle->set_custom_minimum_size(Size2(40, 40));
|
||||
drag_handle->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
|
||||
drag_handle->connect(SceneStringName(gui_input), callable_mp(this, &TouchActionsPanel::_on_drag_handle_gui_input));
|
||||
box->add_child(drag_handle);
|
||||
|
||||
layout_toggle_button = memnew(Button);
|
||||
layout_toggle_button->set_accessibility_name(TTRC("Switch Layout"));
|
||||
layout_toggle_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
layout_toggle_button->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||
layout_toggle_button->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||
layout_toggle_button->connect(SceneStringName(pressed), callable_mp(this, &TouchActionsPanel::_switch_layout));
|
||||
box->add_child(layout_toggle_button);
|
||||
|
||||
lock_panel_button = memnew(Button);
|
||||
lock_panel_button->set_toggle_mode(true);
|
||||
lock_panel_button->set_accessibility_name(TTRC("Lock Panel"));
|
||||
lock_panel_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
lock_panel_button->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||
lock_panel_button->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||
lock_panel_button->connect(SceneStringName(toggled), callable_mp(this, &TouchActionsPanel::_lock_panel_toggled));
|
||||
box->add_child(lock_panel_button);
|
||||
|
||||
ColorRect *separator = memnew(ColorRect);
|
||||
separator->set_color(Color(0.5, 0.5, 0.5));
|
||||
separator->set_custom_minimum_size(Size2(2, 2));
|
||||
box->add_child(separator);
|
||||
|
||||
// Add action buttons.
|
||||
save_button = _add_new_action_button("editor/save_scene", TTR("Save"));
|
||||
delete_button = _add_new_action_button("", TTR("Delete"), Key::KEY_DELETE);
|
||||
undo_button = _add_new_action_button("ui_undo", TTR("Undo"));
|
||||
redo_button = _add_new_action_button("ui_redo", TTR("Redo"));
|
||||
}
|
||||
70
engine/editor/gui/touch_actions_panel.h
Normal file
70
engine/editor/gui/touch_actions_panel.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/**************************************************************************/
|
||||
/* touch_actions_panel.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scene/gui/panel_container.h"
|
||||
|
||||
class BoxContainer;
|
||||
class Button;
|
||||
class TextureRect;
|
||||
|
||||
class TouchActionsPanel : public PanelContainer {
|
||||
GDCLASS(TouchActionsPanel, PanelContainer);
|
||||
|
||||
private:
|
||||
BoxContainer *box = nullptr;
|
||||
Button *save_button = nullptr;
|
||||
Button *delete_button = nullptr;
|
||||
Button *undo_button = nullptr;
|
||||
Button *redo_button = nullptr;
|
||||
|
||||
TextureRect *drag_handle = nullptr;
|
||||
Button *layout_toggle_button = nullptr;
|
||||
Button *lock_panel_button = nullptr;
|
||||
|
||||
bool lock_panel_position = false;
|
||||
bool dragging = false;
|
||||
Vector2 drag_offset;
|
||||
|
||||
void _notification(int p_what);
|
||||
|
||||
void _simulate_editor_shortcut(const String &p_shortcut_name);
|
||||
void _simulate_key_press(Key p_keycode);
|
||||
void _on_drag_handle_gui_input(const Ref<InputEvent> &p_event);
|
||||
void _switch_layout();
|
||||
void _lock_panel_toggled(bool p_pressed);
|
||||
Button *_add_new_action_button(const String &p_shortcut, const String &p_name, Key p_keycode = Key::NONE);
|
||||
|
||||
void _hardware_keyboard_connected(bool p_connected);
|
||||
|
||||
public:
|
||||
TouchActionsPanel();
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue