test-client-godot/addons/input_map_button/input_map_button_node.gd

249 lines
10 KiB
GDScript

tool
extends HBoxContainer
#export(String) var action_name = ""
export(String) var description = "Lorem ipsum."
export(String) var config_file = "user://input.cfg"
export(String) var default_keyboard
export(String) var default_keyboard_alt
export(String) var default_joypad
var action_name
var current_keyboard
func _ready():
action_name = self.name
current_keyboard = $keyboard
load_from_config()
var key_found = false
var key_alt_found = false
for event in InputMap.get_action_list( action_name ):
if event is InputEventKey:
pass
if not key_found:
$keyboard.text = OS.get_scancode_string( event.get_scancode_with_modifiers() )
key_found = true
elif not key_alt_found:
$keyboard_alt.text = OS.get_scancode_string( event.get_scancode_with_modifiers() )
key_alt_found = true
elif event is InputEventJoypadButton:
$joypad.text = Input.get_joy_button_string( event.button_index )
$keyboard.connect( "pressed", self, "wait_for_input" )
$keyboard_alt.connect( "pressed", self, "wait_for_input_alt" )
$joypad.connect( "pressed", self, "wait_for_input" )
set_process_input(false)
func _enter_tree():
if not self.has_node( "description" ):
var new_label = Label.new()
new_label.name = "description"
new_label.text = description
new_label.align = HALIGN_RIGHT
new_label.size_flags_horizontal = SIZE_EXPAND_FILL
new_label.size_flags_vertical = SIZE_EXPAND
self.add_child( new_label )
new_label.set_owner( self )
if not self.has_node( "keyboard" ):
var new_button = Button.new()
new_button.name = "keyboard"
new_button.align = HALIGN_LEFT
new_button.size_flags_horizontal = SIZE_EXPAND_FILL
new_button.size_flags_vertical = SIZE_EXPAND
self.add_child( new_button )
new_button.set_owner( self )
if not self.has_node( "keyboard_alt" ):
var new_button = Button.new()
new_button.name = "keyboard_alt"
new_button.align = HALIGN_LEFT
new_button.size_flags_horizontal = SIZE_EXPAND_FILL
new_button.size_flags_vertical = SIZE_EXPAND
self.add_child( new_button )
new_button.set_owner( self )
#
#
if not self.has_node( "joypad" ):
var new_button_joypad = Button.new()
new_button_joypad.name = "joypad"
new_button_joypad.align = HALIGN_LEFT
new_button_joypad.size_flags_horizontal = SIZE_EXPAND_FILL
new_button_joypad.size_flags_vertical = SIZE_EXPAND
self.add_child( new_button_joypad )
new_button_joypad.set_owner( self )
func get_event_with_modifier_from_string( scancode, type ):
if type == "keyboard":
var new_event = InputEventKey.new()
if not scancode.find( "Meta" ) == -1:
new_event.meta = true
if not scancode.find( "Control" ) == -1:
new_event.control = true
if not scancode.find( "Alt" ) == -1:
new_event.alt = true
if not scancode.find( "Shift" ) == -1:
new_event.shift = true
if not scancode.findn( "+" ) == -1:
scancode = scancode.right(scancode.find_last( "+" )+1)
new_event.scancode = OS.find_scancode_from_string( scancode )
return new_event
elif type == "joypad":
var new_event = InputEventJoypadButton.new()
new_event.button_index = Input.get_joy_button_index_from_string( scancode )
return new_event
return null
func load_from_config():
var config = ConfigFile.new()
var err = config.load( config_file )
if err:# Assuming that file is missing, generate default config
config.save( config_file )
else:
# on initialise l'entrée, si elle n'existe pas déjà, par la valeur par defaut du projet.
if not config.has_section_key("keyboard", action_name):
for event in InputMap.get_action_list( action_name ):
if event is InputEventKey:
var scancode = OS.get_scancode_string( event.get_scancode_with_modifiers() )
config.set_value("keyboard", action_name, scancode)
break
# on initialise l'entrée alternative, si elle n'existe pas déjà, par la valeur par defaut du projet.
var is_first = true
if not config.has_section_key("keyboard_alt", action_name):
for event in InputMap.get_action_list( action_name ):
if not is_first and event is InputEventKey:
var scancode = OS.get_scancode_string( event.get_scancode_with_modifiers() )
config.set_value("keyboard_alt", action_name, scancode)
break
if is_first and event is InputEventKey:
is_first = false
if not config.has_section_key("joypad", action_name):
for event in InputMap.get_action_list( action_name ):
if event is InputEventJoypadButton:
var scancode = Input.get_joy_button_string( event.button_index )
config.set_value("joypad", action_name, scancode)
break
# On efface toutes les touches de clavier de l'InputMap correspondants à l'action en cours.
for old_event in InputMap.get_action_list( action_name ):
if old_event is InputEventKey or old_event is InputEventJoypadButton:
InputMap.action_erase_event(action_name, old_event)
# on recupere les touches du fichier de config et on les ajoutes à l'input map.
if config.has_section("keyboard"):
var action_found = false
for action in config.get_section_keys("keyboard"):
if action == action_name:
action_found = true
var event = get_event_with_modifier_from_string( config.get_value("keyboard", action_name), "keyboard")
InputMap.action_add_event(action_name, event)
break
if config.has_section("keyboard_alt"):
var action_found = false
for action in config.get_section_keys("keyboard_alt"):
if action == action_name:
action_found = true
var event = get_event_with_modifier_from_string( config.get_value("keyboard_alt", action_name), "keyboard")
InputMap.action_add_event(action_name, event)
break
if config.has_section("joypad"):
var action_found = false
for action in config.get_section_keys("joypad"):
if action == action_name:
action_found = true
var event = get_event_with_modifier_from_string( config.get_value("joypad", action_name), "joypad")
for old_event in InputMap.get_action_list( action_name ):
if old_event is InputEventJoypadButton:
InputMap.action_erase_event(action_name, old_event)
InputMap.action_add_event(action_name, event)
config.save( config_file )
func save_to_config(section, key, value):
var config = ConfigFile.new()
var err = config.load( config_file )
if err:
print("Error code when loading config file: ", err)
else:
config.set_value(section, key, value)
config.save( config_file )
# Input management
func wait_for_input():
current_keyboard = $keyboard
set_process_input(true)
func wait_for_input_alt():
current_keyboard = $keyboard_alt
set_process_input(true)
# Input management
func _input(event):
if event is InputEventKey and not event.pressed and not event.is_echo():
var input_string = OS.get_scancode_string( event.scancode )
if not event.is_action("ui_cancel") \
and not input_string == "Meta" \
and not input_string == "Control" \
and not input_string == "Alt" \
and not input_string == "Shift" \
:
get_tree().set_input_as_handled()
set_process_input( false )
current_keyboard.text = ""
if event.meta:
current_keyboard.text += "Meta+"
if event.control:
current_keyboard.text += "Control+"
if event.alt:
current_keyboard.text += "Alt+"
if event.shift:
current_keyboard.text += "Shift+"
current_keyboard.text += input_string
var change_first_key = true
if current_keyboard.name == "keyboard_alt":
change_first_key = false
var is_first_key = true
for old_event in InputMap.get_action_list( action_name ):
if old_event is InputEventKey:
if is_first_key:
if change_first_key:
InputMap.action_erase_event(action_name, old_event)
is_first_key = false
elif not change_first_key:
InputMap.action_erase_event(action_name, old_event)
InputMap.action_add_event(action_name, event)
save_to_config(current_keyboard.name, action_name, current_keyboard.text)
elif event is InputEventJoypadButton and not event.pressed and not event.is_echo():
var input_string = Input.get_joy_button_string( event.button_index )
get_tree().set_input_as_handled()
set_process_input( false )
$joypad.text = input_string
for old_event in InputMap.get_action_list( action_name ):
if old_event is InputEventJoypadButton:
InputMap.action_erase_event(action_name, old_event)
InputMap.action_add_event(action_name, event)
save_to_config("joypad", action_name, $joypad.text)