addon for remapping inputs
save and load the inputmap
| -rw-r--r-- | addons/remap/ActionLabel.gd | 2 | ||||
| -rw-r--r-- | addons/remap/InteractiveActionLabel.gd | 15 | ||||
| -rw-r--r-- | addons/remap/KeyPromptLabel.gd | 18 | ||||
| -rw-r--r-- | addons/remap/KeySelector.gd | 2 | ||||
| -rw-r--r-- | addons/remap/RemapUtilities.gd | 20 | ||||
| -rw-r--r-- | addons/remap/SaveLoadUtils.gd | 55 | ||||
| -rw-r--r-- | icon.png | bin | 11691 -> 0 bytes | |||
| -rw-r--r-- | icon.png.import | 35 | ||||
| -rw-r--r-- | project.godot | 12 |
9 files changed, 98 insertions, 61 deletions
diff --git a/addons/remap/ActionLabel.gd b/addons/remap/ActionLabel.gd index 0de8bb9..ff98108 100644 --- a/addons/remap/ActionLabel.gd +++ b/addons/remap/ActionLabel.gd @@ -10,6 +10,8 @@ var name_label := Label.new() func _ready() -> void: + SaveLoadUtils.create_dir(SaveLoadUtils.dir) + SaveLoadUtils.load2inputmap(action) name_label.text = _name name_label.valign = Label.VALIGN_CENTER name_label.align = Label.ALIGN_CENTER diff --git a/addons/remap/InteractiveActionLabel.gd b/addons/remap/InteractiveActionLabel.gd index 064fdbb..9fd313f 100644 --- a/addons/remap/InteractiveActionLabel.gd +++ b/addons/remap/InteractiveActionLabel.gd @@ -1,15 +1,16 @@ extends ActionLabel class_name InteractiveActionLabel - # if this is overriden, the new scene must # - have a confirmed(action: InputEvent) signal # - have a cancelled() signal # - free itself when one of them is emitted export(PackedScene) var popup = preload("./KeySelector.tscn") +var clear := Button.new() + + func _ready(): - var clear := Button.new() clear.theme = preload("./main.theme") clear.text = "✗" clear.connect("pressed", self, "clear") @@ -17,19 +18,25 @@ func _ready(): clear.rect_min_size.x = 30 add_child(clear) move_child(clear, 0) + clear.visible = InputMap.get_action_list(action).size() > 0 func _gui_input(event: InputEvent): if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed: var selector = popup.instance() add_child(selector) - selector.connect("confirmed",self,"_on_key_selected") + selector.connect("confirmed", self, "_on_key_selected") func _on_key_selected(event: InputEvent): - RemapUtilities.add_action(action,event) + RemapUtilities.add_action(action, event) icons._update() + SaveLoadUtils.inputmap2file(action) + clear.show() + func clear(): RemapUtilities.clear_mappings(action) icons._update() + SaveLoadUtils.inputmap2file(action) + clear.hide() diff --git a/addons/remap/KeyPromptLabel.gd b/addons/remap/KeyPromptLabel.gd index 9844a49..9dbb499 100644 --- a/addons/remap/KeyPromptLabel.gd +++ b/addons/remap/KeyPromptLabel.gd @@ -1,27 +1,11 @@ extends Label -const motions = [ - InputEventMouseMotion, - InputEventJoypadMotion, - InputEventScreenDrag, - InputEventScreenTouch, - InputEventMIDI, - InputEventMouseButton -] - var selected: InputEvent func _input(event: InputEvent) -> void: - if check_is(event, motions): + if !RemapUtilities.is_valid_action(event): return $"%ok".disabled = false selected = event text = IconMap.get_icon(event) - - -func check_is(it, is_it_a: Array) -> bool: - for i in is_it_a: - if it is i: - return true - return false diff --git a/addons/remap/KeySelector.gd b/addons/remap/KeySelector.gd index edf27f4..13234c2 100644 --- a/addons/remap/KeySelector.gd +++ b/addons/remap/KeySelector.gd @@ -9,10 +9,12 @@ func _ready(): $"%ok".connect("pressed", self, "confirmed") $"%cancel".connect("pressed", self, "cancelled") + func confirmed(): emit_signal("confirmed", $"%KeyPrompter".selected) queue_free() + func cancelled(): emit_signal("cancelled") queue_free() diff --git a/addons/remap/RemapUtilities.gd b/addons/remap/RemapUtilities.gd index 74e237f..dce3e84 100644 --- a/addons/remap/RemapUtilities.gd +++ b/addons/remap/RemapUtilities.gd @@ -1,10 +1,26 @@ extends Reference class_name RemapUtilities +const invalid_actions = [ + InputEventMouseMotion, + InputEventJoypadMotion, + InputEventScreenDrag, + InputEventScreenTouch, + InputEventMIDI, + InputEventMouseButton +] -static func clear_mappings(action: String): + +static func clear_mappings(action: String) -> void: InputMap.action_erase_events(action) -static func add_action(action: String, event: InputEvent): +static func add_action(action: String, event: InputEvent) -> void: InputMap.action_add_event(action, event) + + +static func is_valid_action(e: InputEvent) -> bool: + for i in invalid_actions: + if e is i: + return false + return true diff --git a/addons/remap/SaveLoadUtils.gd b/addons/remap/SaveLoadUtils.gd new file mode 100644 index 0000000..869305a --- /dev/null +++ b/addons/remap/SaveLoadUtils.gd @@ -0,0 +1,55 @@ +#warning-ignore-all: return_value_discarded +extends Node +class_name SaveLoadUtils + +const dir := "user://__inputs__" +const path_template := "user://__inputs__/%s.res" + + +static func save(path: String, data: Dictionary) -> void: + var file := File.new() + file.open(path, File.WRITE) + file.store_string(var2str(data)) + file.close() + + +static func load_file(path: String) -> Dictionary: + var file := File.new() + if file.file_exists(path): + file.open(path, File.READ) + var text := file.get_as_text() + var dict := {} + if text: + dict = str2var(text) + file.close() + return dict + save(path, {}) # create file if it doesn't exist + return {} + + +# mkdir -p +static func create_dir(path: String) -> int: + var dir := Directory.new() + return dir.make_dir_recursive(path) + + +static func inputmap2file(action: String) -> void: + var list := InputMap.get_action_list(action) + var data := {actions = list} + save(path_template % action, data) + + +static func load2inputmap(action: String) -> void: + var data := load_file(path_template % action) + if typeof(data) == TYPE_DICTIONARY and typeof(data.get("actions", false)) == TYPE_ARRAY: + for e in data.actions: # validate + if e is InputEvent and RemapUtilities.is_valid_action(e): + continue + inputmap2file(action) # reset if invalid + push_error("Invalid action: %s" % action) + return + RemapUtilities.clear_mappings(action) + for e in data.actions: + RemapUtilities.add_action(action, e) + return + inputmap2file(action) diff --git a/icon.png b/icon.png Binary files differdeleted file mode 100644 index 8a4e86b..0000000 --- a/icon.png +++ /dev/null diff --git a/icon.png.import b/icon.png.import deleted file mode 100644 index a4c02e6..0000000 --- a/icon.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://icon.png" -dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/project.godot b/project.godot index 97d96f9..fd08610 100644 --- a/project.godot +++ b/project.godot @@ -38,6 +38,11 @@ _global_script_classes=[ { "class": "RemapUtilities", "language": "GDScript", "path": "res://addons/remap/RemapUtilities.gd" +}, { +"base": "Node", +"class": "SaveLoadUtils", +"language": "GDScript", +"path": "res://addons/remap/SaveLoadUtils.gd" } ] _global_script_class_icons={ "ActionIcons": "", @@ -45,15 +50,16 @@ _global_script_class_icons={ "IconMap": "", "InteractiveActionLabel": "", "KeySelector": "", -"RemapUtilities": "" +"RemapUtilities": "", +"SaveLoadUtils": "" } [application] -config/name="Godot Template" +config/name="test" run/main_scene="res://Test.tscn" config/use_custom_user_dir=true -config/custom_user_dir_name="GodotTemplate" +config/custom_user_dir_name="remap" [debug] |