Skip to content

Commit 6f4a3e8

Browse files
committed
Move early hotkey bind handling into KeychainShortcutEdit Add hotkey reset warning
1 parent 671eabc commit 6f4a3e8

32 files changed

+908
-84
lines changed

game/addons/keychain/Keychain.gd

Lines changed: 105 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
extends Node
22

3-
const PROFILES_PATH := "user://shortcut_profiles"
3+
signal profile_switched(profile: ShortcutProfile)
4+
signal action_changed(action_name: String)
45

5-
signal reload_keychain()
6+
const PROFILES_PATH := "user://shortcut_profiles"
7+
const DEFAULT_PROFILE := preload("profiles/default.tres")
68

79
## [Array] of [ShortcutProfile]s.
8-
var profiles: Array[ShortcutProfile] = [preload("profiles/default.tres")]
9-
var selected_profile := profiles[0] ## The currently selected [ShortcutProfile].
10+
var profiles: Array[ShortcutProfile] = []
11+
var selected_profile: ShortcutProfile ## The currently selected [ShortcutProfile].
1012
var profile_index := 0 ## The index of the currently selected [ShortcutProfile].
11-
## [Dictionary] of [String] and [InputAction].
1213
## Syntax: "action_name": InputAction.new("Action Display Name", "Group", true)
1314
## Note that "action_name" must already exist in the Project's Input Map.
14-
var actions := {}
15-
## [Dictionary] of [String] and [InputGroup].
15+
var actions: Dictionary[StringName, InputAction] = {}
1616
## Syntax: "Group Name": InputGroup.new("Parent Group Name")
17-
var groups := {}
17+
var groups: Dictionary[StringName, InputGroup] = {}
1818
var ignore_actions: Array[StringName] = [] ## [Array] of [StringName] input map actions to ignore.
1919
## If [code]true[/code], ignore Godot's default "ui_" input map actions.
2020
var ignore_ui_actions := true
@@ -37,12 +37,77 @@ class InputAction:
3737
var group := ""
3838
var global := true
3939

40-
func _init(_display_name := "", _group := "", _global := true):
40+
func _init(_display_name := "", _group := "", _global := true) -> void:
4141
display_name = _display_name
4242
group = _group
4343
global = _global
4444

4545

46+
class MouseMovementInputAction:
47+
extends InputAction
48+
49+
var action_name := &""
50+
## The default direction of the mouse, towards where the value increments.
51+
## This should be set only once during an instance's initialization.
52+
var default_mouse_dir := Vector2.RIGHT
53+
## The default sensitivity of the mouse for the value to change.
54+
## This should be set only once during an instance's initialization.
55+
var default_sensitivity := 0.1
56+
57+
var mouse_dir := default_mouse_dir
58+
var sensitivity := default_sensitivity:
59+
set(value):
60+
if is_zero_approx(value):
61+
sensitivity = 0.001
62+
else:
63+
sensitivity = value
64+
65+
var motion_accum := 0.0
66+
67+
func _init(
68+
_display_name := "",
69+
_group := "",
70+
_global := true,
71+
_action_name := &"",
72+
_default_mouse_dir := Vector2.RIGHT,
73+
_default_sensitivity := 0.1
74+
) -> void:
75+
super(_display_name, _group, _global)
76+
action_name = _action_name
77+
default_mouse_dir = _default_mouse_dir
78+
default_sensitivity = _default_sensitivity
79+
80+
func get_action_distance(event: InputEvent, exact_match := false) -> float:
81+
if event is InputEventMouseMotion and Input.is_action_pressed(action_name, exact_match):
82+
var relative := (event as InputEventMouseMotion).relative
83+
var delta := relative.dot(mouse_dir.normalized()) * sensitivity
84+
return delta
85+
return 0.0
86+
87+
func get_action_distance_int(event: InputEvent, exact_match := false) -> int:
88+
if event is InputEventMouseMotion and Input.is_action_pressed(action_name, exact_match):
89+
var relative := (event as InputEventMouseMotion).relative
90+
var delta := relative.dot(mouse_dir.normalized()) * sensitivity
91+
motion_accum += delta
92+
93+
var step := int(motion_accum)
94+
motion_accum -= step
95+
96+
return step
97+
return 0
98+
99+
func restore_to_default() -> void:
100+
mouse_dir = default_mouse_dir
101+
sensitivity = default_sensitivity
102+
103+
func serialize() -> Dictionary:
104+
return {"mouse_dir": mouse_dir, "sensitivity": sensitivity}
105+
106+
func deserialize(dict: Dictionary) -> void:
107+
mouse_dir = dict.get("mouse_dir", mouse_dir)
108+
sensitivity = dict.get("sensitivity", sensitivity)
109+
110+
46111
class InputGroup:
47112
var parent_group := ""
48113
var folded := true
@@ -57,6 +122,7 @@ func _init() -> void:
57122
for locale in TranslationServer.get_loaded_locales():
58123
load_translation(locale)
59124

125+
60126
func _ready() -> void:
61127
if !config_file:
62128
config_file = ConfigFile.new()
@@ -73,38 +139,54 @@ func _ready() -> void:
73139
if file_name.get_extension() == "tres":
74140
var file := load(PROFILES_PATH.path_join(file_name))
75141
if file is ShortcutProfile:
142+
file.fill_bindings()
76143
profiles.append(file)
77144
file_name = profile_dir.get_next()
78145

79146
# If there are no profiles besides the default, create one custom
80-
if profiles.size() == 1:
147+
if profiles.size() == 0:
81148
var profile := ShortcutProfile.new()
82149
profile.name = "Custom"
83150
profile.resource_path = PROFILES_PATH.path_join("custom.tres")
84151
var saved := profile.save()
85152
if saved:
86153
profiles.append(profile)
87-
88-
initialize_profiles()
89-
90-
func initialize_profiles() -> void:
91-
for profile in profiles:
92-
profile.fill_bindings()
93-
94154
profile_index = config_file.get_value("shortcuts", "shortcuts_profile", 0)
95155
change_profile(profile_index)
96-
Keychain.reload_keychain.emit()
156+
97157

98158
func change_profile(index: int) -> void:
99159
if index >= profiles.size():
100160
index = profiles.size() - 1
101161
profile_index = index
102162
selected_profile = profiles[index]
103-
for action in selected_profile.bindings:
104-
if not InputMap.has_action(action): continue
105-
action_erase_events(action)
106-
for event in selected_profile.bindings[action]:
107-
action_add_event(action, event)
163+
for action_name in selected_profile.bindings:
164+
if not InputMap.has_action(action_name):
165+
continue
166+
action_erase_events(action_name)
167+
for event in selected_profile.bindings[action_name]:
168+
action_add_event(action_name, event)
169+
if actions.has(action_name):
170+
var input_action := actions[action_name]
171+
if input_action is MouseMovementInputAction:
172+
if selected_profile.mouse_movement_options.has(action_name):
173+
var mm_options := selected_profile.mouse_movement_options[action_name]
174+
input_action.deserialize(mm_options)
175+
else:
176+
input_action.restore_to_default()
177+
profile_switched.emit(selected_profile)
178+
179+
180+
func change_action(action_name: String) -> void:
181+
selected_profile.change_action(action_name)
182+
action_changed.emit(action_name)
183+
184+
185+
func change_mouse_movement_action_settings(action: MouseMovementInputAction) -> void:
186+
var action_name := action.action_name
187+
selected_profile.mouse_movement_options[action_name] = action.serialize()
188+
selected_profile.save()
189+
action_changed.emit(action_name)
108190

109191

110192
func action_add_event(action: StringName, event: InputEvent) -> void:
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
uid://ba4bw6vqtoail
1+
uid://dgiia2xg7fsud

0 commit comments

Comments
 (0)