godot-accessibility/addons/accessibility/accessible.gd

310 lines
9.0 KiB
GDScript3
Raw Normal View History

extends Object
2019-09-02 12:04:45 +00:00
var tts
var node
2018-07-19 20:12:01 +00:00
var position_in_children = 0
var column_in_row = 0
func get_siblings():
var parent = node.get_parent()
if parent:
return parent.get_children()
return null
2018-06-10 21:14:43 +00:00
func item_or_items(count):
if count == 1:
return "item"
else:
return "items"
func button_focus():
2019-09-03 22:43:20 +00:00
print(node.get_parent())
2019-09-02 12:04:45 +00:00
var text
2018-06-10 20:32:27 +00:00
if node.text:
text = node.text
if text:
tts.speak("%s: button" % text, false)
else:
tts.speak("button", false)
2018-06-10 20:32:27 +00:00
func item_list_focus():
2018-07-03 17:01:00 +00:00
var count = node.get_item_count()
var selected = node.get_selected_items()
tts.speak("list, %s %s" % [count, item_or_items(count)], false)
2019-09-02 12:04:45 +00:00
tts.speak(selected, false)
2018-07-03 17:01:00 +00:00
2019-09-02 12:04:45 +00:00
func item_list_item_selected(index):
tts.speak("Selected", false)
2018-07-03 17:01:00 +00:00
2019-09-02 12:04:45 +00:00
func item_list_multi_selected(index, selected):
tts.speak("Multiselect", false)
2018-07-03 17:01:00 +00:00
2019-09-02 12:04:45 +00:00
func item_list_nothing_selected():
tts.speak("Nothing selected", false)
2018-07-03 17:01:00 +00:00
func item_list_input(event):
if event.echo or not event.pressed:
return
var old_pos = position_in_children
if event.scancode == KEY_UP:
node.get_tree().set_input_as_handled()
2018-07-19 20:12:01 +00:00
if position_in_children == 0:
return
2018-07-19 20:12:01 +00:00
position_in_children -= 1
elif event.scancode == KEY_DOWN:
node.get_tree().set_input_as_handled()
2018-07-19 20:12:01 +00:00
if position_in_children >= node.get_item_count()-1:
return
2018-07-19 20:12:01 +00:00
position_in_children += 1
elif event.scancode == KEY_HOME:
2018-07-19 20:12:01 +00:00
position_in_children = 0
elif event.scancode == KEY_END:
2018-07-19 20:12:01 +00:00
position_in_children = node.get_item_count()-1
if old_pos != position_in_children:
var text = node.get_item_text(position_in_children)
tts.speak("%s: %s of %s" % [text, position_in_children+1, node.get_item_count()], false)
2018-06-10 21:14:43 +00:00
func label_focus():
2019-09-02 12:04:45 +00:00
var text = node.text
if text == "":
text = "blank"
tts.speak(text, false)
func line_edit_focus():
2018-06-10 20:32:27 +00:00
var text = "blank"
if node.secret:
text = "password"
elif node.text != "":
text = node.text
elif node.placeholder_text != "":
text = node.placeholder_text
var type = "editable text"
if not node.editable:
type = "text"
tts.speak("%s: %s" % [text, type], false)
2018-06-10 20:32:27 +00:00
func text_deleted(text):
2019-09-02 12:04:45 +00:00
tts.speak("%s deleted" % text, true)
func text_inserted(text):
2019-09-02 12:04:45 +00:00
tts.speak(text, true)
2018-06-18 20:33:03 +00:00
var old_pos
func check_caret_moved():
var pos = node.caret_position
if old_pos != null and old_pos != pos:
2018-06-18 20:33:03 +00:00
var text = node.text
if pos > len(text)-1:
2019-09-02 12:04:45 +00:00
tts.speak("blank", true)
2018-06-18 20:33:03 +00:00
else:
2019-09-02 12:04:45 +00:00
tts.speak(text[pos], true)
2018-06-18 20:33:03 +00:00
old_pos = pos
elif old_pos == null:
old_pos = pos
func menu_button_focus():
tts.speak(node.text + ": menu", false)
2019-09-02 12:04:45 +00:00
func popup_menu_focus():
tts.speak("menu", false)
2018-07-19 20:12:01 +00:00
func popup_menu_item_id_focus(id):
2019-09-02 12:04:45 +00:00
print("id: %s" % id)
print("count: %s" % node.get_item_count())
2018-07-19 20:12:01 +00:00
var item = node.get_item_text(id)
2019-09-02 12:04:45 +00:00
var submenu = node.get_item_submenu(id)
2018-07-19 20:12:01 +00:00
var tooltip = node.get_item_tooltip(position_in_children)
2019-09-02 12:04:45 +00:00
print("Tooltip: %s" % tooltip)
var disabled = node.is_item_disabled(id)
2018-07-19 20:12:01 +00:00
if item and tooltip:
2019-09-02 12:04:45 +00:00
print("Got item and tooltip")
2018-07-19 20:12:01 +00:00
item += ": "
item += tooltip
elif tooltip:
2019-09-02 12:04:45 +00:00
print("Got tooltip only")
2018-07-19 20:12:01 +00:00
item = tooltip
var shortcut = node.get_item_shortcut(position_in_children)
2019-09-02 12:04:45 +00:00
if shortcut != null and shortcut.get_as_text() != "None":
print("Got shortcut: %s" % shortcut.get_as_text())
2018-07-19 20:12:01 +00:00
item += ": "+shortcut.get_as_text()
2019-09-02 12:04:45 +00:00
if item == "":
item = "Unlabelled"
if submenu:
item += ": menu"
if disabled:
item += ": disabled"
item += ": " + str(id + 1) + " of " + str(node.get_item_count())
tts.speak(item, true)
2018-07-19 20:12:01 +00:00
func tree_item_render():
var focused_tree_item = node.get_selected()
var result = ""
for i in range(node.columns):
result += focused_tree_item.get_text(i) + ": "
if focused_tree_item.get_children():
if focused_tree_item.collapsed:
result += "collapsed "
else:
result += "expanded "
result += "tree item"
if focused_tree_item.is_selected(0):
result += ": selected"
tts.speak(result, true)
2018-07-19 17:02:40 +00:00
2019-09-03 22:22:02 +00:00
var prev_selected_cell
func tree_item_selected():
var cell = node.get_selected()
if cell != prev_selected_cell:
print("New cell")
tree_item_render()
prev_selected_cell = cell
else:
var text = ""
for i in range(node.columns):
if cell.is_selected(i):
var title = node.get_column_title(i)
if title:
text += title + ": "
text += cell.get_text(i) + ", "
if text != "":
tts.speak(text, true)
func tree_item_multi_select(item, column, selected):
if selected:
tts.speak("selected", true)
else:
tts.speak("unselected", true)
func tree_focus():
if node.get_selected():
tree_item_render()
else:
tts.speak("tree", true)
func tree_item_collapse(item):
if node.has_focus():
if item.collapsed:
tts.speak("collapsed", true)
else:
tts.speak("expanded", true)
func tab_container_focus():
2019-09-02 14:55:51 +00:00
var text = node.get_tab_title(node.current_tab)
text += ": tab: " + str(node.current_tab + 1) + " of " + str(node.get_tab_count())
tts.speak(text, false)
func tab_container_input(event):
2019-09-02 14:55:51 +00:00
if event.echo or not event.pressed:
return
var new_tab = node.current_tab
2019-09-02 14:55:51 +00:00
if event.scancode == KEY_RIGHT:
new_tab += 1
elif event.scancode == KEY_LEFT:
new_tab -= 1
if new_tab < 0:
new_tab = node.get_tab_count() - 1
elif new_tab >= node.get_tab_count():
new_tab = 0
if node.current_tab != new_tab:
node.current_tab = new_tab
tts.stop()
tab_container_focus()
2018-06-10 21:02:45 +00:00
2018-05-28 21:45:13 +00:00
func focused():
2019-09-02 12:04:45 +00:00
print("Focus: %s" % node)
tts.stop()
var parent = node.get_parent()
if parent is EditorProperty and parent.label:
tts.speak(parent.label, false)
2018-07-19 20:12:01 +00:00
if node is MenuButton:
menu_button_focus()
2018-07-19 20:12:01 +00:00
elif node is Button:
button_focus()
2018-06-10 21:14:43 +00:00
elif node is ItemList:
item_list_focus()
elif node is Label:
label_focus()
2018-06-10 20:32:27 +00:00
elif node is LineEdit:
line_edit_focus()
2018-07-19 20:12:01 +00:00
elif node is PopupMenu:
popup_menu_focus()
2019-09-02 14:55:51 +00:00
elif node is TabContainer:
tab_container_focus()
2018-06-10 21:02:45 +00:00
elif node is Tree:
tree_focus()
2018-06-10 20:18:00 +00:00
else:
2019-09-02 12:04:45 +00:00
print("No handler")
if node.hint_tooltip:
2019-09-02 12:04:45 +00:00
tts.speak(node.hint_tooltip, false)
2018-05-28 21:45:13 +00:00
func unfocused():
2018-07-19 20:12:01 +00:00
position_in_children = 0
func gui_input(event):
2019-09-02 14:55:51 +00:00
if node is TabContainer:
return tab_container_input(event)
elif node is ItemList:
return item_list_input(event)
2018-07-19 20:12:01 +00:00
elif node is LineEdit:
return check_caret_moved()
elif event.is_action_pressed("ui_left"):
return node.accept_event()
elif event.is_action_pressed("ui_right"):
return node.accept_event()
elif event.is_action_pressed("ui_up"):
return node.accept_event()
elif event.is_action_pressed("ui_down"):
return node.accept_event()
func is_in_bar():
var parent = node.get_parent()
if parent and parent is Container:
for child in parent.get_children():
if child and not is_focusable(child):
return false
return true
return false
func is_focusable(node):
2019-09-03 22:43:20 +00:00
if node is TabContainer:
return true
if node is Container or node is Panel or node is Separator or node is ScrollBar or node is Popup or node.get_class() == "Control":
return false
return true
2019-09-02 12:04:45 +00:00
func _init(tts, node):
if node.is_in_group("accessible"):
return
node.add_to_group("accessible")
2019-09-02 12:04:45 +00:00
self.tts = tts
self.node = node
if is_focusable(node):
2019-09-02 14:55:51 +00:00
node.set_focus_mode(Control.FOCUS_ALL)
2018-07-03 16:42:00 +00:00
node.connect("focus_entered", self, "focused")
node.connect("mouse_entered", self, "focused")
node.connect("focus_exited", self, "unfocused")
node.connect("mouse_exited", self, "unfocused")
node.connect("gui_input", self, "gui_input")
if node is ItemList:
2019-09-02 12:04:45 +00:00
node.connect("item_selected", self, "item_list_item_selected")
node.connect("multi_selected", self, "item_list_multi_selected")
node.connect("nothing_selected", self, "item_list_nothing_selected")
# elif node is LineEdit:
# node.connect("text_deleted", self, "text_deleted")
# node.connect("text_inserted", self, "text_inserted")
2018-07-19 20:12:01 +00:00
elif node is PopupMenu:
node.connect("id_focused", self, "popup_menu_item_id_focus")
2018-07-19 17:02:40 +00:00
elif node is Tree:
node.connect("item_collapsed", self, "tree_item_collapse")
node.connect("multi_selected", self, "tree_item_multi_select")
2019-09-03 22:22:02 +00:00
if node.select_mode == Tree.SELECT_MULTI:
node.connect("cell_selected", self, "tree_item_selected")
else:
node.connect("item_selected", self, "tree_item_selected")
2018-07-03 16:42:00 +00:00
node.connect("tree_exiting", self, "free")