11extends 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].
1012var 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 ] = {}
1818var 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.
2020var 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+
46111class 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+
60126func _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
98158func 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
110192func action_add_event (action : StringName , event : InputEvent ) -> void :
0 commit comments