Skip to content

Commit

Permalink
fix(Search Bar): add keyboard support for search bar
Browse files Browse the repository at this point in the history
- Update search bar to use LineEdit instead of TextEdit
- Add ability to move text cursor with OSK
- Switch to library state upon keyboard input
  • Loading branch information
ShadowApex committed Dec 28, 2024
1 parent 411ad5e commit 6a9ef5f
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 33 deletions.
14 changes: 13 additions & 1 deletion core/global/keyboard_instance.gd
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ var context: KeyboardContext
# keyboard inputs should go, and how to handle submits.
func open(ctx: KeyboardContext) -> void:
set_context(ctx)
if context and context.target:
# Show the caret
if context.target is LineEdit:
var line_edit := context.target as LineEdit
line_edit.caret_force_displayed = true
# Some nodes (like LineEdit), will grab focus when text is manipulated.
# Don't allow the node to grab focus
context.target.focus_mode = Control.FOCUS_NONE
keyboard_opened.emit()


Expand All @@ -27,6 +35,11 @@ func close() -> void:
# If the target is a control node, return focus back to it when the
# keyboard closes
if context and context.target:
# Hide the caret
if context.target is LineEdit:
var line_edit := context.target as LineEdit
line_edit.caret_force_displayed = false
context.target.focus_mode = Control.FOCUS_ALL
context.target.grab_focus.call_deferred()
set_context(null)
keyboard_closed.emit()
Expand All @@ -48,7 +61,6 @@ func set_context(ctx: KeyboardContext) -> void:
text_edit.set_caret_line(lines-1)
var current_line := text_edit.get_line(lines-1)
text_edit.set_caret_column(current_line.length())
#text_edit.clear()

# Update our internal keyboard context
if context == ctx:
Expand Down
6 changes: 3 additions & 3 deletions core/ui/card_ui/navigation/search_bar_menu.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ var default_size := Vector2(custom_minimum_size.x, custom_minimum_size.y)

@export var animate_time := 0.2

@onready var tabs_container := $%LibraryTabsContainer
@onready var search_bar := $%SearchBar
@onready var search_button := $%SearchButton
@onready var tabs_container := $%LibraryTabsContainer as TabsHeader
@onready var search_bar := $%SearchBar as SearchBar
@onready var search_button := $%SearchButton as CardIconButton


# Called when the node enters the scene tree for the first time.
Expand Down
19 changes: 12 additions & 7 deletions core/ui/card_ui/navigation/search_bar_menu.tscn
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
[gd_scene load_steps=12 format=3 uid="uid://d4bmkauhrlhq0"]
[gd_scene load_steps=13 format=3 uid="uid://d4bmkauhrlhq0"]

[ext_resource type="Script" path="res://core/ui/card_ui/navigation/search_bar_menu.gd" id="1_518qs"]
[ext_resource type="PackedScene" uid="uid://bx0fnuxd8mm51" path="res://core/ui/components/search_bar.tscn" id="2_gqstr"]
[ext_resource type="Resource" uid="uid://oaavalv0wcoa" path="res://assets/state/states/home.tres" id="2_kr4pi"]
[ext_resource type="PackedScene" uid="uid://bfiia7vnbfw3s" path="res://core/systems/state/states_watcher.tscn" id="2_nb2d7"]
[ext_resource type="Resource" uid="uid://boq501bigx8kl" path="res://assets/state/states/library.tres" id="3_sj5or"]
[ext_resource type="Script" path="res://core/systems/state/state.gd" id="3_truj2"]
[ext_resource type="PackedScene" uid="uid://bw8113ocotx2r" path="res://core/systems/effects/fade_effect.tscn" id="4_1043g"]
[ext_resource type="Texture2D" uid="uid://8pmccsyfv3u7" path="res://assets/ui/icons/search.svg" id="5_pq07x"]
[ext_resource type="PackedScene" uid="uid://cr83fmlociwko" path="res://core/ui/components/card_icon_button.tscn" id="6_dilc0"]
[ext_resource type="PackedScene" uid="uid://cgmb4kr2ec4ha" path="res://core/ui/components/tabs_header.tscn" id="8_uixir"]
[ext_resource type="Resource" uid="uid://cjda3nse6s3n1" path="res://core/ui/card_ui/library/library_tabs_state.tres" id="9_dlgkq"]
[ext_resource type="Script" path="res://core/ui/components/input_icon.gd" id="9_qnoau"]
[ext_resource type="Script" path="res://core/ui/components/search_bar.gd" id="9_smv7o"]

[node name="SearchBarMenu" type="PanelContainer"]
z_index = 19
Expand All @@ -21,7 +22,7 @@ theme_type_variation = &"SearchBar"
script = ExtResource("1_518qs")

[node name="StatesWatcher" parent="." instance=ExtResource("2_nb2d7")]
states = Array[Resource("res://core/systems/state/state.gd")]([ExtResource("2_kr4pi"), ExtResource("3_sj5or")])
states = Array[ExtResource("3_truj2")]([ExtResource("2_kr4pi"), ExtResource("3_sj5or")])

[node name="FadeEffect" parent="StatesWatcher" node_paths=PackedStringArray("target") instance=ExtResource("4_1043g")]
target = NodePath("../..")
Expand All @@ -47,13 +48,17 @@ texture = ExtResource("5_pq07x")
layout_mode = 2
theme_override_constants/separation = 1

[node name="SearchBar" parent="MarginContainer/HBoxContainer/HBoxContainer" groups=["global_search_bar"] instance=ExtResource("2_gqstr")]
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HBoxContainer/HBoxContainer"]
layout_mode = 2
theme_override_constants/margin_top = 5
theme_override_constants/margin_bottom = 5

[node name="SearchBar" type="LineEdit" parent="MarginContainer/HBoxContainer/HBoxContainer/MarginContainer" groups=["global_search_bar", "search_bar"]]
unique_name_in_owner = true
custom_minimum_size = Vector2(250, 36)
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
theme_override_colors/background_color = Color(0, 0, 0, 0)
theme_override_font_sizes/font_size = 15
placeholder_text = "What should you play?"
script = ExtResource("9_smv7o")

[node name="InputIcon" type="HBoxContainer" parent="MarginContainer/HBoxContainer/HBoxContainer"]
layout_mode = 2
Expand Down
32 changes: 23 additions & 9 deletions core/ui/common/osk/on_screen_keyboard.gd
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func open() -> void:
break

# Try to scroll any scroll containers to the target node
var target = instance.context.target
var target := instance.context.target
if target:
# TODO: Find a better way to scroll to the focused element after grow
# effect finishes
Expand Down Expand Up @@ -211,18 +211,20 @@ func open() -> void:

# Closes the OSK
func close() -> void:
# Remove the OSK state
popup_state_machine.remove_state(osk_state)

# If the keyboard is configured to send input to the game, set gamescope accordinly
var xwayland := gamescope.get_xwayland(gamescope.XWAYLAND_TYPE_OGUI)
var pid := OS.get_process_id()
var ogui_windows := xwayland.get_windows_for_pid(pid)
if not ogui_windows.is_empty():
var overlay_window_id := ogui_windows[0]
if state_machine.current_state() == in_game_state:
xwayland.set_input_focus(overlay_window_id, 0)
else:
xwayland.set_input_focus(overlay_window_id, 1)
if xwayland:
var pid := OS.get_process_id()
var ogui_windows := xwayland.get_windows_for_pid(pid)
if not ogui_windows.is_empty():
var overlay_window_id := ogui_windows[0]
if state_machine.current_state() == in_game_state:
xwayland.set_input_focus(overlay_window_id, 0)
else:
xwayland.set_input_focus(overlay_window_id, 1)

closed.emit()

Expand Down Expand Up @@ -393,6 +395,7 @@ func _handle_native(key: KeyboardKeyConfig) -> void:
if target is LineEdit:
var line_edit := instance.context.target as LineEdit
line_edit.insert_text_at_caret(character)
line_edit.text_changed.emit(line_edit.text) # insert_text doesn't fire this signal
return

logger.warn("Keyboard target is not a supported type. Can't send key input.")
Expand All @@ -404,6 +407,16 @@ func _handle_native_action(key: KeyboardKeyConfig) -> void:
return
var target = instance.context.target
match key.input.keycode:
KEY_LEFT:
if target != null and target is LineEdit:
var line_edit := target as LineEdit
if line_edit.caret_column > 0:
line_edit.caret_column -= 1
KEY_RIGHT:
if target != null and target is LineEdit:
var line_edit := target as LineEdit
if line_edit.caret_column < line_edit.text.length():
line_edit.caret_column += 1
KEY_SHIFT:
if _mode_shift > MODE_SHIFT.OFF:
set_mode_shift(MODE_SHIFT.OFF)
Expand All @@ -423,6 +436,7 @@ func _handle_native_action(key: KeyboardKeyConfig) -> void:
if target != null and target is LineEdit:
var line_edit := target as LineEdit
line_edit.delete_char_at_caret()
# Upon delete, the LineEdit grabs focus
return
KEY_ENTER:
instance.context.submitted.emit()
Expand Down
9 changes: 6 additions & 3 deletions core/ui/components/search_bar.gd
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
extends TextEdit
extends LineEdit
class_name SearchBar

signal search_submitted(text: String)

var state_machine := load("res://assets/state/state_machines/menu_state_machine.tres") as StateMachine
var library_state := load("res://assets/state/states/library.tres")
var library_state := load("res://assets/state/states/library.tres") as State

var keyboard_context := KeyboardContext.new(KeyboardContext.TYPE.GODOT, self)
@export var keyboard: KeyboardInstance = preload("res://core/global/keyboard_instance.tres")
Expand All @@ -16,7 +16,10 @@ func _ready() -> void:
text_changed.connect(_on_text_changed)


func _on_text_changed() -> void:
func _on_text_changed(new_text: String) -> void:
if state_machine.current_state() != library_state:
state_machine.push_state(library_state)
grab_focus.call_deferred()
search_submitted.emit(text)


Expand Down
10 changes: 0 additions & 10 deletions core/ui/components/search_bar.tscn

This file was deleted.

0 comments on commit 6a9ef5f

Please sign in to comment.