249 lines
10 KiB
GDScript
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)
|
|
|