mirror of https://github.com/godotengine/godot
Merge pull request #113915 from ydeltastar/game-view-node-lock
Prevent locked and child nodes of selection groups from being selected in the Game view
This commit is contained in:
commit
08e6cd181f
|
|
@ -95,6 +95,12 @@ void GameViewDebugger::_session_started(Ref<EditorDebuggerSession> p_session) {
|
|||
Array mode;
|
||||
mode.append(select_mode);
|
||||
p_session->send_message("scene:runtime_node_select_set_mode", mode);
|
||||
Array avoid_locked;
|
||||
avoid_locked.append(selection_avoid_locked);
|
||||
p_session->send_message("scene:runtime_node_select_set_avoid_locked", avoid_locked);
|
||||
Array prefer_group;
|
||||
prefer_group.append(selection_prefer_group);
|
||||
p_session->send_message("scene:runtime_node_select_set_prefer_group", prefer_group);
|
||||
Array mute_audio_data;
|
||||
mute_audio_data.append(mute_audio);
|
||||
p_session->send_message("scene:debug_mute_audio", mute_audio_data);
|
||||
|
|
@ -183,6 +189,32 @@ void GameViewDebugger::set_selection_visible(bool p_visible) {
|
|||
}
|
||||
}
|
||||
|
||||
void GameViewDebugger::set_selection_avoid_locked(bool p_enabled) {
|
||||
selection_avoid_locked = p_enabled;
|
||||
|
||||
Array message;
|
||||
message.append(p_enabled);
|
||||
|
||||
for (Ref<EditorDebuggerSession> &I : sessions) {
|
||||
if (I->is_active()) {
|
||||
I->send_message("scene:runtime_node_select_set_avoid_locked", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameViewDebugger::set_selection_prefer_group(bool p_enabled) {
|
||||
selection_prefer_group = p_enabled;
|
||||
|
||||
Array message;
|
||||
message.append(p_enabled);
|
||||
|
||||
for (Ref<EditorDebuggerSession> &I : sessions) {
|
||||
if (I->is_active()) {
|
||||
I->send_message("scene:runtime_node_select_set_prefer_group", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameViewDebugger::set_select_mode(int p_mode) {
|
||||
select_mode = p_mode;
|
||||
|
||||
|
|
@ -596,6 +628,25 @@ void GameView::_select_mode_pressed(int p_option) {
|
|||
EditorSettings::get_singleton()->set_project_metadata("game_view", "select_mode", mode);
|
||||
}
|
||||
|
||||
void GameView::_selection_options_menu_id_pressed(int p_id) {
|
||||
switch (p_id) {
|
||||
case SELECTION_AVOID_LOCKED: {
|
||||
selection_avoid_locked = !selection_avoid_locked;
|
||||
debugger->set_selection_avoid_locked(selection_avoid_locked);
|
||||
EditorSettings::get_singleton()->set_project_metadata("game_view", "selection_avoid_locked", selection_avoid_locked);
|
||||
} break;
|
||||
case SELECTION_PREFER_GROUP: {
|
||||
selection_prefer_group = !selection_prefer_group;
|
||||
debugger->set_selection_prefer_group(selection_prefer_group);
|
||||
EditorSettings::get_singleton()->set_project_metadata("game_view", "selection_prefer_group", selection_prefer_group);
|
||||
} break;
|
||||
}
|
||||
|
||||
PopupMenu *menu = selection_options_menu->get_popup();
|
||||
menu->set_item_checked(menu->get_item_index(SELECTION_AVOID_LOCKED), selection_avoid_locked);
|
||||
menu->set_item_checked(menu->get_item_index(SELECTION_PREFER_GROUP), selection_prefer_group);
|
||||
}
|
||||
|
||||
void GameView::_embed_options_menu_menu_id_pressed(int p_id) {
|
||||
switch (p_id) {
|
||||
case EMBED_RUN_GAME_EMBEDDED: {
|
||||
|
|
@ -880,6 +931,7 @@ void GameView::_notification(int p_what) {
|
|||
select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->set_button_icon(get_editor_theme_icon(SNAME("ListSelect")));
|
||||
|
||||
hide_selection->set_button_icon(get_editor_theme_icon(hide_selection->is_pressed() ? SNAME("GuiVisibilityHidden") : SNAME("GuiVisibilityVisible")));
|
||||
selection_options_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
|
||||
embed_options_menu->set_button_icon(get_editor_theme_icon(SNAME("KeepAspect")));
|
||||
|
||||
debug_mute_audio_button->set_button_icon(get_editor_theme_icon(debug_mute_audio ? SNAME("AudioMute") : SNAME("AudioStreamPlayer")));
|
||||
|
|
@ -1272,6 +1324,26 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
|
|||
}
|
||||
hide_selection->connect(SceneStringName(toggled), callable_mp(this, &GameView::_hide_selection_toggled));
|
||||
|
||||
selection_options_menu = memnew(MenuButton);
|
||||
selection_hb->add_child(selection_options_menu);
|
||||
selection_options_menu->set_flat(false);
|
||||
selection_options_menu->set_theme_type_variation("FlatMenuButton");
|
||||
selection_options_menu->set_h_size_flags(SIZE_SHRINK_END);
|
||||
selection_options_menu->set_tooltip_text(TTRC("Selection Options"));
|
||||
|
||||
PopupMenu *selection_menu = selection_options_menu->get_popup();
|
||||
selection_menu->connect(SceneStringName(id_pressed), callable_mp(this, &GameView::_selection_options_menu_id_pressed));
|
||||
selection_menu->add_check_item(TTRC("Don't Select Locked Nodes"), SELECTION_AVOID_LOCKED);
|
||||
selection_menu->add_check_item(TTRC("Select Group Over Children"), SELECTION_PREFER_GROUP);
|
||||
|
||||
selection_avoid_locked = EditorSettings::get_singleton()->get_project_metadata("game_view", "selection_avoid_locked", false);
|
||||
selection_prefer_group = EditorSettings::get_singleton()->get_project_metadata("game_view", "selection_prefer_group", false);
|
||||
selection_menu->set_item_checked(selection_menu->get_item_index(SELECTION_AVOID_LOCKED), selection_avoid_locked);
|
||||
selection_menu->set_item_checked(selection_menu->get_item_index(SELECTION_PREFER_GROUP), selection_prefer_group);
|
||||
|
||||
debugger->set_selection_avoid_locked(selection_avoid_locked);
|
||||
debugger->set_selection_prefer_group(selection_prefer_group);
|
||||
|
||||
selection_hb->add_child(memnew(VSeparator));
|
||||
|
||||
HBoxContainer *audio_hb = memnew(HBoxContainer);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ private:
|
|||
bool mute_audio = false;
|
||||
EditorDebuggerNode::CameraOverride camera_override_mode = EditorDebuggerNode::OVERRIDE_INGAME;
|
||||
|
||||
bool selection_avoid_locked = false;
|
||||
bool selection_prefer_group = false;
|
||||
|
||||
void _session_started(Ref<EditorDebuggerSession> p_session);
|
||||
void _session_stopped();
|
||||
|
||||
|
|
@ -90,6 +93,9 @@ public:
|
|||
|
||||
void set_selection_visible(bool p_visible);
|
||||
|
||||
void set_selection_avoid_locked(bool p_enabled);
|
||||
void set_selection_prefer_group(bool p_enabled);
|
||||
|
||||
void set_debug_mute_audio(bool p_enabled);
|
||||
|
||||
void set_camera_override(bool p_enabled);
|
||||
|
|
@ -113,6 +119,8 @@ class GameView : public VBoxContainer {
|
|||
CAMERA_MODE_EDITORS,
|
||||
EMBED_RUN_GAME_EMBEDDED,
|
||||
EMBED_MAKE_FLOATING_ON_PLAY,
|
||||
SELECTION_AVOID_LOCKED,
|
||||
SELECTION_PREFER_GROUP,
|
||||
};
|
||||
|
||||
enum EmbedSizeMode {
|
||||
|
|
@ -153,6 +161,9 @@ class GameView : public VBoxContainer {
|
|||
|
||||
bool debug_mute_audio = false;
|
||||
|
||||
bool selection_avoid_locked = false;
|
||||
bool selection_prefer_group = false;
|
||||
|
||||
Button *suspend_button = nullptr;
|
||||
Button *next_frame_button = nullptr;
|
||||
|
||||
|
|
@ -160,6 +171,7 @@ class GameView : public VBoxContainer {
|
|||
Button *select_mode_button[RuntimeNodeSelect::SELECT_MODE_MAX];
|
||||
|
||||
Button *hide_selection = nullptr;
|
||||
MenuButton *selection_options_menu = nullptr;
|
||||
|
||||
Button *debug_mute_audio_button = nullptr;
|
||||
|
||||
|
|
@ -191,6 +203,7 @@ class GameView : public VBoxContainer {
|
|||
|
||||
void _node_type_pressed(int p_option);
|
||||
void _select_mode_pressed(int p_option);
|
||||
void _selection_options_menu_id_pressed(int p_id);
|
||||
void _embed_options_menu_menu_id_pressed(int p_id);
|
||||
|
||||
void _reset_time_scales();
|
||||
|
|
|
|||
|
|
@ -415,6 +415,20 @@ Error SceneDebugger::_msg_runtime_node_select_set_visible(const Array &p_args) {
|
|||
return OK;
|
||||
}
|
||||
|
||||
Error SceneDebugger::_msg_runtime_node_select_set_avoid_locked(const Array &p_args) {
|
||||
ERR_FAIL_COND_V(p_args.is_empty(), ERR_INVALID_DATA);
|
||||
bool avoid_locked = p_args[0];
|
||||
RuntimeNodeSelect::get_singleton()->_set_avoid_locked(avoid_locked);
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error SceneDebugger::_msg_runtime_node_select_set_prefer_group(const Array &p_args) {
|
||||
ERR_FAIL_COND_V(p_args.is_empty(), ERR_INVALID_DATA);
|
||||
bool prefer_group = p_args[0];
|
||||
RuntimeNodeSelect::get_singleton()->_set_prefer_group(prefer_group);
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error SceneDebugger::_msg_runtime_node_select_reset_camera_2d(const Array &p_args) {
|
||||
RuntimeNodeSelect::get_singleton()->_reset_camera_2d();
|
||||
return OK;
|
||||
|
|
@ -567,6 +581,8 @@ void SceneDebugger::_init_message_handlers() {
|
|||
message_handlers["runtime_node_select_set_type"] = _msg_runtime_node_select_set_type;
|
||||
message_handlers["runtime_node_select_set_mode"] = _msg_runtime_node_select_set_mode;
|
||||
message_handlers["runtime_node_select_set_visible"] = _msg_runtime_node_select_set_visible;
|
||||
message_handlers["runtime_node_select_set_avoid_locked"] = _msg_runtime_node_select_set_avoid_locked;
|
||||
message_handlers["runtime_node_select_set_prefer_group"] = _msg_runtime_node_select_set_prefer_group;
|
||||
message_handlers["runtime_node_select_reset_camera_2d"] = _msg_runtime_node_select_reset_camera_2d;
|
||||
#ifndef _3D_DISABLED
|
||||
message_handlers["runtime_node_select_reset_camera_3d"] = _msg_runtime_node_select_reset_camera_3d;
|
||||
|
|
@ -1859,18 +1875,6 @@ void RuntimeNodeSelect::_physics_frame() {
|
|||
}
|
||||
}
|
||||
|
||||
// Remove possible duplicates.
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Node *item = items[i].item;
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (items[j].item == item) {
|
||||
items.remove_at(i);
|
||||
i--;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef _3D_DISABLED
|
||||
} else if (node_select_type == NODE_TYPE_3D) {
|
||||
if (selection_drag_valid) {
|
||||
|
|
@ -1881,6 +1885,57 @@ void RuntimeNodeSelect::_physics_frame() {
|
|||
#endif // _3D_DISABLED
|
||||
}
|
||||
|
||||
if ((prefer_group_selection || avoid_locked_nodes) && !list_shortcut_pressed && node_select_mode == SELECT_MODE_SINGLE) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Node *node = items[i].item;
|
||||
Node *final_node = node;
|
||||
real_t order = items[i].order;
|
||||
|
||||
// Replace the node by the group if grouped.
|
||||
if (prefer_group_selection) {
|
||||
while (node && node != root) {
|
||||
if (node->has_meta("_edit_group_")) {
|
||||
final_node = node;
|
||||
|
||||
if (Object::cast_to<CanvasItem>(final_node)) {
|
||||
CanvasItem *ci_tmp = Object::cast_to<CanvasItem>(final_node);
|
||||
order = ci_tmp->get_effective_z_index() + ci_tmp->get_canvas_layer();
|
||||
} else if (Object::cast_to<Node3D>(final_node)) {
|
||||
Node3D *node3d_tmp = Object::cast_to<Node3D>(final_node);
|
||||
Camera3D *camera = root->get_camera_3d();
|
||||
Vector3 pos = camera->project_ray_origin(selection_position);
|
||||
order = -pos.distance_to(node3d_tmp->get_global_transform().origin);
|
||||
}
|
||||
}
|
||||
node = node->get_parent();
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out locked nodes.
|
||||
if (avoid_locked_nodes && final_node->get_meta("_edit_lock_", false)) {
|
||||
items.remove_at(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
items.write[i].item = final_node;
|
||||
items.write[i].order = order;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove possible duplicates.
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Node *item = items[i].item;
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (items[j].item == item) {
|
||||
items.remove_at(i);
|
||||
i--;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items.sort();
|
||||
|
||||
switch (selection_drag_state) {
|
||||
|
|
@ -2334,7 +2389,29 @@ void RuntimeNodeSelect::_open_selection_list(const Vector<SelectResult> &p_items
|
|||
root->add_child(selection_list);
|
||||
|
||||
for (const SelectResult &I : p_items) {
|
||||
selection_list->add_item(I.item->get_name());
|
||||
int locked = 0;
|
||||
if (I.item->get_meta("_edit_lock_", false)) {
|
||||
locked = 1;
|
||||
} else {
|
||||
Node *scene = SceneTree::get_singleton()->get_root();
|
||||
Node *node = I.item;
|
||||
|
||||
while (node && node != scene->get_parent()) {
|
||||
if (node->has_meta("_edit_group_")) {
|
||||
locked = 2;
|
||||
}
|
||||
node = node->get_parent();
|
||||
}
|
||||
}
|
||||
|
||||
String suffix;
|
||||
if (locked == 1) {
|
||||
suffix = " (" + RTR("Locked") + ")";
|
||||
} else if (locked == 2) {
|
||||
suffix = " (" + RTR("Grouped") + ")";
|
||||
}
|
||||
|
||||
selection_list->add_item((String)I.item->get_name() + suffix);
|
||||
selection_list->set_item_metadata(-1, I.item);
|
||||
}
|
||||
|
||||
|
|
@ -2358,6 +2435,14 @@ void RuntimeNodeSelect::_set_selection_visible(bool p_visible) {
|
|||
}
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_set_avoid_locked(bool p_enabled) {
|
||||
avoid_locked_nodes = p_enabled;
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_set_prefer_group(bool p_enabled) {
|
||||
prefer_group_selection = p_enabled;
|
||||
}
|
||||
|
||||
// Copied and trimmed from the CanvasItemEditor implementation.
|
||||
void RuntimeNodeSelect::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<SelectResult> &r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
|
||||
if (!p_node || Object::cast_to<Viewport>(p_node)) {
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@ private:
|
|||
static Error _msg_runtime_node_select_set_type(const Array &p_args);
|
||||
static Error _msg_runtime_node_select_set_mode(const Array &p_args);
|
||||
static Error _msg_runtime_node_select_set_visible(const Array &p_args);
|
||||
static Error _msg_runtime_node_select_set_avoid_locked(const Array &p_args);
|
||||
static Error _msg_runtime_node_select_set_prefer_group(const Array &p_args);
|
||||
static Error _msg_rq_screenshot(const Array &p_args);
|
||||
|
||||
static Error _msg_runtime_node_select_reset_camera_2d(const Array &p_args);
|
||||
|
|
@ -280,6 +282,9 @@ private:
|
|||
bool selection_visible = true;
|
||||
bool selection_update_queued = false;
|
||||
|
||||
bool avoid_locked_nodes = false;
|
||||
bool prefer_group_selection = false;
|
||||
|
||||
bool multi_shortcut_pressed = false;
|
||||
bool list_shortcut_pressed = false;
|
||||
RID draw_canvas;
|
||||
|
|
@ -396,6 +401,8 @@ private:
|
|||
void _clear_selection();
|
||||
void _update_selection_drag(const Point2 &p_end_pos = Point2());
|
||||
void _set_selection_visible(bool p_visible);
|
||||
void _set_avoid_locked(bool p_enabled);
|
||||
void _set_prefer_group(bool p_enabled);
|
||||
|
||||
void _open_selection_list(const Vector<SelectResult> &p_items, const Point2 &p_pos);
|
||||
void _close_selection_list();
|
||||
|
|
|
|||
Loading…
Reference in New Issue