Selaa lähdekoodia

Merge pull request #105518 from syntaxerror247/fixed-panel

Embed TouchActionsPanel directly into the Android editor UI
Thaddeus Crews 4 kuukautta sitten
vanhempi
commit
8868c7a329

+ 4 - 4
doc/classes/EditorSettings.xml

@@ -1105,10 +1105,6 @@
 			If [code]true[/code], enable two finger pan and scale gestures on touchscreen devices.
 			[b]Note:[/b] Defaults to [code]true[/code] on touchscreen devices.
 		</member>
-		<member name="interface/touchscreen/enable_touch_actions_panel" type="bool" setter="" getter="">
-			If [code]true[/code], enables the TouchActionsPanel to provide easy access to keyboard shortcuts on touchscreen devices.
-			[b]Note:[/b] Only available in the Android editor.
-		</member>
 		<member name="interface/touchscreen/increase_scrollbar_touch_area" type="bool" setter="" getter="">
 			If [code]true[/code], increases the scrollbar touch area to improve usability on touchscreen devices.
 			[b]Note:[/b] Defaults to [code]true[/code] on touchscreen devices.
@@ -1117,6 +1113,10 @@
 			Specify the multiplier to apply to the scale for the editor gizmo handles to improve usability on touchscreen devices.
 			[b]Note:[/b] Defaults to [code]1[/code] on non-touchscreen devices.
 		</member>
+		<member name="interface/touchscreen/touch_actions_panel" type="int" setter="" getter="">
+			A touch-friendly panel that provides easy access to common actions such as save, delete, undo, and redo without requiring a keyboard.
+			[b]Note:[/b] Only available in the Android and XR editor.
+		</member>
 		<member name="network/connection/check_for_updates" type="int" setter="" getter="">
 			Specifies how the engine should check for updates.
 			- [b]Disable Update Checks[/b] will block the engine from checking updates (see also [member network/connection/network_mode]).

+ 46 - 8
editor/editor_node.cpp

@@ -940,6 +940,11 @@ void EditorNode::_notification(int p_what) {
 			if (EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/theme/highlighting")) {
 				EditorHelpHighlighter::get_singleton()->reset_cache();
 			}
+#endif
+#ifdef ANDROID_ENABLED
+			if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/touch_actions_panel")) {
+				_touch_actions_panel_mode_changed();
+			}
 #endif
 		} break;
 	}
@@ -7063,6 +7068,34 @@ void EditorNode::set_unfocused_low_processor_usage_mode_enabled(bool p_enabled)
 	unfocused_low_processor_usage_mode_enabled = p_enabled;
 }
 
+#ifdef ANDROID_ENABLED
+void EditorNode::_touch_actions_panel_mode_changed() {
+	int panel_mode = EDITOR_GET("interface/touchscreen/touch_actions_panel");
+	switch (panel_mode) {
+		case 1:
+			if (touch_actions_panel != nullptr) {
+				touch_actions_panel->queue_free();
+			}
+			touch_actions_panel = memnew(TouchActionsPanel);
+			main_hbox->call_deferred("add_child", touch_actions_panel);
+			break;
+		case 2:
+			if (touch_actions_panel != nullptr) {
+				touch_actions_panel->queue_free();
+			}
+			touch_actions_panel = memnew(TouchActionsPanel);
+			call_deferred("add_child", touch_actions_panel);
+			break;
+		case 0:
+			if (touch_actions_panel != nullptr) {
+				touch_actions_panel->queue_free();
+				touch_actions_panel = nullptr;
+			}
+			break;
+	}
+}
+#endif
+
 EditorNode::EditorNode() {
 	DEV_ASSERT(!singleton);
 	singleton = this;
@@ -7368,7 +7401,20 @@ EditorNode::EditorNode() {
 	gui_base->set_end(Point2(0, 0));
 
 	main_vbox = memnew(VBoxContainer);
+
+#ifdef ANDROID_ENABLED
+	main_hbox = memnew(HBoxContainer);
+	main_hbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
+
+	main_hbox->add_child(main_vbox);
+	main_vbox->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+
+	_touch_actions_panel_mode_changed();
+
+	gui_base->add_child(main_hbox);
+#else
 	gui_base->add_child(main_vbox);
+#endif
 
 	title_bar = memnew(EditorTitleBar);
 	main_vbox->add_child(title_bar);
@@ -7952,14 +7998,6 @@ EditorNode::EditorNode() {
 
 	_update_layouts_menu();
 
-#ifdef ANDROID_ENABLED
-	// Add TouchActionsPanel node.
-	bool is_enabled = EDITOR_GET("interface/touchscreen/enable_touch_actions_panel");
-	if (is_enabled) {
-		add_child(memnew(TouchActionsPanel));
-	}
-#endif
-
 	// Bottom panels.
 
 	bottom_panel = memnew(EditorBottomPanel);

+ 11 - 0
editor/editor_node.h

@@ -99,6 +99,11 @@ class ProjectSettingsEditor;
 class SceneImportSettingsDialog;
 class ProjectUpgradeTool;
 
+#ifdef ANDROID_ENABLED
+class HBoxContainer;
+class TouchActionsPanel;
+#endif
+
 struct EditorProgress {
 	String task;
 	bool force_background = false;
@@ -276,6 +281,12 @@ private:
 	VBoxContainer *main_vbox = nullptr;
 	OptionButton *renderer = nullptr;
 
+#ifdef ANDROID_ENABLED
+	HBoxContainer *main_hbox = nullptr; // Only created on Android for TouchActionsPanel.
+	TouchActionsPanel *touch_actions_panel = nullptr;
+	void _touch_actions_panel_mode_changed();
+#endif
+
 	ConfirmationDialog *video_restart_dialog = nullptr;
 
 	int renderer_current = 0;

+ 4 - 4
editor/editor_settings.cpp

@@ -584,10 +584,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 	EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/touchscreen/scale_gizmo_handles", has_touchscreen_ui ? 3 : 1, "1,5,1")
 	set_restart_if_changed("interface/touchscreen/scale_gizmo_handles", true);
 
-	// Only available in the Android editor.
-	EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/touchscreen/enable_touch_actions_panel", true, "")
-	set_restart_if_changed("interface/touchscreen/enable_touch_actions_panel", true);
-
 	// Disable some touchscreen settings by default for the XR Editor.
 	bool is_native_touchscreen = has_touchscreen_ui && !OS::get_singleton()->has_feature("xr_editor");
 	EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/touchscreen/enable_long_press_as_right_click", is_native_touchscreen, "")
@@ -595,6 +591,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 	EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/touchscreen/increase_scrollbar_touch_area", is_native_touchscreen, "")
 	set_restart_if_changed("interface/touchscreen/increase_scrollbar_touch_area", true);
 
+	// Only available in the Android editor.
+	String touch_actions_panel_hints = "Disabled:0,Embedded Panel:1,Floating Panel:2";
+	EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/touchscreen/touch_actions_panel", 1, touch_actions_panel_hints)
+
 	// Scene tabs
 	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/scene_tabs/display_close_button", 1, "Never,If Tab Active,Always"); // TabBar::CloseButtonDisplayPolicy
 	_initial_set("interface/scene_tabs/show_thumbnail_on_hover", true);

+ 84 - 36
editor/gui/touch_actions_panel.cpp

@@ -44,14 +44,25 @@ void TouchActionsPanel::_notification(int 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());
+			if (!is_floating) {
+				get_parent()->move_child(this, embedded_panel_index);
+			}
 		} break;
 		case NOTIFICATION_VISIBILITY_CHANGED: {
 			set_process_input(is_visible_in_tree());
 		} 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")));
+			if (is_floating) {
+				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")));
+			} else {
+				if (embedded_panel_index == 1) {
+					panel_pos_button->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignLeftWide")));
+				} else {
+					panel_pos_button->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignRightWide")));
+				}
+			}
 			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")));
@@ -154,7 +165,7 @@ void TouchActionsPanel::_add_new_modifier_button(Modifier p_modifier) {
 }
 
 void TouchActionsPanel::_on_drag_handle_gui_input(const Ref<InputEvent> &p_event) {
-	if (lock_panel_position) {
+	if (locked_panel) {
 		return;
 	}
 	Ref<InputEventMouseButton> mouse_button_event = p_event;
@@ -191,50 +202,87 @@ void TouchActionsPanel::_switch_layout() {
 }
 
 void TouchActionsPanel::_lock_panel_toggled(bool p_pressed) {
-	lock_panel_position = p_pressed;
-	layout_toggle_button->set_disabled(p_pressed);
+	locked_panel = p_pressed;
+	layout_toggle_button->set_visible(!p_pressed);
+	drag_handle->set_visible(!p_pressed);
+	reset_size();
+	queue_redraw();
+}
+
+void TouchActionsPanel::_switch_embedded_panel_side() {
+	if (embedded_panel_index == 0) {
+		embedded_panel_index = 1;
+		panel_pos_button->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignLeftWide")));
+	} else {
+		embedded_panel_index = 0;
+		panel_pos_button->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignRightWide")));
+	}
+	get_parent()->move_child(this, embedded_panel_index); // Parent is a hbox with only two children -- TouchActionsPanel and main Editor UI.
+	EditorSettings::get_singleton()->set("_touch_actions_panel_embed_index", embedded_panel_index);
+	EditorSettings::get_singleton()->save();
 }
 
 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);
+	int panel_mode = EDITOR_GET("interface/touchscreen/touch_actions_panel");
+	is_floating = panel_mode == 2;
+
+	if (is_floating) {
+		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_position(EDITOR_DEF("_touch_actions_panel_position", Point2(480, 480))); // Dropped it here for no good reason — users can move it anyway.
+		set_position(EDITOR_DEF("_touch_actions_panel_position", Point2(480, 480))); // Dropped it here for no good reason — users can move it anyway.
+	}
 
 	box = memnew(BoxContainer);
 	box->set_alignment(BoxContainer::ALIGNMENT_CENTER);
 	box->add_theme_constant_override("separation", 20);
-	box->set_vertical(EDITOR_DEF("_touch_actions_panel_vertical_layout", false));
+	if (is_floating) {
+		box->set_vertical(EDITOR_DEF("_touch_actions_panel_vertical_layout", false));
+	} else {
+		box->set_vertical(true);
+	}
 	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);
+	if (is_floating) {
+		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_theme_type_variation("FlatMenuButton");
+		layout_toggle_button->set_accessibility_name(TTRC("Switch Layout"));
+		layout_toggle_button->set_focus_mode(FOCUS_NONE);
+		layout_toggle_button->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+		layout_toggle_button->connect(SceneStringName(pressed), callable_mp(this, &TouchActionsPanel::_switch_layout));
+		box->add_child(layout_toggle_button);
 
-	layout_toggle_button = memnew(Button);
-	layout_toggle_button->set_theme_type_variation("FlatMenuButton");
-	layout_toggle_button->set_accessibility_name(TTRC("Switch Layout"));
-	layout_toggle_button->set_focus_mode(FOCUS_NONE);
-	layout_toggle_button->set_icon_alignment(HORIZONTAL_ALIGNMENT_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_theme_type_variation("FlatMenuButton");
+		lock_panel_button->set_accessibility_name(TTRC("Lock Panel"));
+		lock_panel_button->set_focus_mode(FOCUS_NONE);
+		lock_panel_button->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+		lock_panel_button->connect(SceneStringName(toggled), callable_mp(this, &TouchActionsPanel::_lock_panel_toggled));
+		box->add_child(lock_panel_button);
+	} else {
+		panel_pos_button = memnew(Button);
+		panel_pos_button->set_theme_type_variation("FlatMenuButton");
+		panel_pos_button->set_accessibility_name(TTRC("Switch Embedded Panel Position"));
+		panel_pos_button->set_focus_mode(FOCUS_NONE);
+		panel_pos_button->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+		panel_pos_button->connect(SceneStringName(pressed), callable_mp(this, &TouchActionsPanel::_switch_embedded_panel_side));
+		box->add_child(panel_pos_button);
 
-	lock_panel_button = memnew(Button);
-	lock_panel_button->set_toggle_mode(true);
-	lock_panel_button->set_theme_type_variation("FlatMenuButton");
-	lock_panel_button->set_accessibility_name(TTRC("Lock Panel"));
-	lock_panel_button->set_focus_mode(FOCUS_NONE);
-	lock_panel_button->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
-	lock_panel_button->connect(SceneStringName(toggled), callable_mp(this, &TouchActionsPanel::_lock_panel_toggled));
-	box->add_child(lock_panel_button);
+		embedded_panel_index = EDITOR_DEF("_touch_actions_panel_embed_index", 0);
+	}
 
 	ColorRect *separator = memnew(ColorRect);
 	separator->set_color(Color(0.5, 0.5, 0.5));

+ 7 - 2
editor/gui/touch_actions_panel.h

@@ -52,8 +52,9 @@ private:
 	TextureRect *drag_handle = nullptr;
 	Button *layout_toggle_button = nullptr;
 	Button *lock_panel_button = nullptr;
+	Button *panel_pos_button = nullptr;
 
-	bool lock_panel_position = false;
+	bool locked_panel = false;
 	bool dragging = false;
 	Vector2 drag_offset;
 
@@ -67,6 +68,9 @@ private:
 	bool shift_btn_pressed = false;
 	bool alt_btn_pressed = false;
 
+	bool is_floating = false; // Embedded panel mode is default.
+	int embedded_panel_index = 0;
+
 	void _notification(int p_what);
 	virtual void input(const Ref<InputEvent> &event) override;
 
@@ -75,8 +79,9 @@ private:
 	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 _switch_embedded_panel_side();
 
+	Button *_add_new_action_button(const String &p_shortcut, const String &p_name, Key p_keycode = Key::NONE);
 	void _add_new_modifier_button(Modifier p_modifier);
 	void _on_modifier_button_toggled(bool p_pressed, int p_modifier);