Skip to content

Commit

Permalink
Input improvements and Text Settings cleanup (#2189)
Browse files Browse the repository at this point in the history
- should replace #2183

Thanks so much to @StrangeLost to bringing this to my attention and providing a MRP!

- uses is_action_JUST_pressed for input handling, avoiding issues where by having the mouse pressed and moving while advancing, you could trigger advance twice.
- move skip delay blocking to the beginning of text events
- expose "Advance Delay"
- cleanup text settings scene/script
  • Loading branch information
Jowan-Spooner authored Apr 18, 2024
1 parent 46764c8 commit f3b0604
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 137 deletions.
4 changes: 2 additions & 2 deletions addons/dialogic/Modules/Core/subsystem_input.gd
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func handle_input() -> void:

## Unhandled Input is used for all NON-Mouse based inputs.
func _unhandled_input(event:InputEvent) -> void:
if Input.is_action_pressed(ProjectSettings.get_setting('dialogic/text/input_action', 'dialogic_default_action')):
if Input.is_action_just_pressed(ProjectSettings.get_setting('dialogic/text/input_action', 'dialogic_default_action')):
if event is InputEventMouse:
return
handle_input()
Expand All @@ -97,7 +97,7 @@ func _unhandled_input(event:InputEvent) -> void:
## Input is used for all mouse based inputs.
## If any DialogicInputNode is present this won't do anything (because that node handles MouseInput then).
func _input(event:InputEvent) -> void:
if Input.is_action_pressed(ProjectSettings.get_setting('dialogic/text/input_action', 'dialogic_default_action')):
if Input.is_action_just_pressed(ProjectSettings.get_setting('dialogic/text/input_action', 'dialogic_default_action')):

if not event is InputEventMouse or get_tree().get_nodes_in_group('dialogic_input').any(func(node):return node.is_visible_in_tree()):
return
Expand Down
3 changes: 1 addition & 2 deletions addons/dialogic/Modules/Text/event_text.gd
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func _execute() -> void:
reveal_next_segment = false

for section_idx in range(min(dialogic.current_state_info['text_sub_idx'], len(split_text)-1), len(split_text)):
dialogic.Inputs.block_input(ProjectSettings.get_setting('dialogic/text/text_reveal_skip_delay', 0.1))

if reveal_next_segment:
dialogic.Text.hide_next_indicators()
Expand Down Expand Up @@ -218,12 +219,10 @@ func _on_dialogic_input_action() -> void:
if dialogic.Text.is_text_reveal_skippable():
dialogic.Text.skip_text_reveal()
dialogic.Inputs.stop_timers()
dialogic.Inputs.block_input(ProjectSettings.get_setting('dialogic/text/text_reveal_skip_delay', 0.1))
_:
if dialogic.Inputs.manual_advance.is_enabled():
advance.emit()
dialogic.Inputs.stop_timers()
dialogic.Inputs.block_input(ProjectSettings.get_setting('dialogic/text/text_reveal_skip_delay', 0.1))


func _on_dialogic_input_autoadvance() -> void:
Expand Down
3 changes: 1 addition & 2 deletions addons/dialogic/Modules/Text/node_dialog_text.gd
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ func continue_reveal() -> void:
finish_text()
# if the text finished organically, add a small input block
# this prevents accidental skipping when you expected the text to be longer
# TODO! Make this configurable in the settings!
DialogicUtil.autoload().Inputs.block_input(0.3)
DialogicUtil.autoload().Inputs.block_input(ProjectSettings.get_setting('dialogic/text/advance_delay', 0.1))


## Reveals the entire text instantly.
Expand Down
218 changes: 120 additions & 98 deletions addons/dialogic/Modules/Text/settings_text.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,31 @@ extends DialogicSettingsPage

var autopause_sets := {}

const _SETTING_LETTER_SPEED := 'dialogic/text/letter_speed'

const _SETTING_INPUT_ACTION := 'dialogic/text/input_action'

const _SETTING_TEXT_REVEAL_SKIPPABLE := 'dialogic/text/initial_text_reveal_skippable'
const _SETTING_TEXT_REVEAL_SKIPPABLE_DELAY := 'dialogic/text/text_reveal_skip_delay'
const _SETTING_TEXT_ADVANCE_DELAY := 'dialogic/text/advance_delay'

const _SETTING_AUTOCOLOR_NAMES := 'dialogic/text/autocolor_names'
const _SETTING_SPLIT_AT_NEW_LINES := 'dialogic/text/split_at_new_lines'
const _SETTING_SPLIT_AT_NEW_LINES_AS := 'dialogic/text/split_at_new_lines_as'

const _SETTING_AUTOSKIP_TIME_PER_EVENT := 'dialogic/text/autoskip_time_per_event'

const _SETTING_AUTOADVANCE_ENABLED := 'dialogic/text/autoadvance_enabled'
const _SETTING_AUTOADVANCE_FIXED_DELAY := 'dialogic/text/autoadvance_fixed_delay'
const _SETTING_AUTOADVANCE_WORD_DELAY := 'dialogic/text/autoadvance_per_word_delay'
const _SETTING_AUTOADVANCE_CHARACTER_DELAY := 'dialogic/text/autoadvance_per_character_delay'
const _SETTING_AUTOADVANCE_IGNORED_CHARACTERS_ENABLED := 'dialogic/text/autoadvance_ignored_characters_enabled'
const _SETTING_AUTOADVANCE_IGNORED_CHARACTERS := 'dialogic/text/autoadvance_ignored_characters'

const _SETTING_ABSOLUTE_AUTOPAUSES := 'dialogic/text/absolute_autopauses'
const _SETTING_AUTOPAUSES := 'dialogic/text/autopauses'


func _get_priority() -> int:
return 98

Expand All @@ -11,144 +36,157 @@ func _get_title() -> String:
return "Text"


func _ready() -> void:
%DefaultSpeed.value_changed.connect(_on_float_set.bind(_SETTING_LETTER_SPEED))

%Skippable.toggled.connect(_on_bool_set.bind(_SETTING_TEXT_REVEAL_SKIPPABLE))
%SkippableDelay.value_changed.connect(_on_float_set.bind(_SETTING_TEXT_REVEAL_SKIPPABLE_DELAY))
%AdvanceDelay.value_changed.connect(_on_float_set.bind(_SETTING_TEXT_ADVANCE_DELAY))

%AutocolorNames.toggled.connect(_on_bool_set.bind(_SETTING_AUTOCOLOR_NAMES))

%NewEvents.toggled.connect(_on_bool_set.bind(_SETTING_SPLIT_AT_NEW_LINES))

%AutoAdvance.toggled.connect(_on_bool_set.bind(_SETTING_AUTOADVANCE_ENABLED))
%FixedDelay.value_changed.connect(_on_float_set.bind(_SETTING_AUTOADVANCE_FIXED_DELAY))
%IgnoredCharactersEnabled.toggled.connect(_on_bool_set.bind(_SETTING_AUTOADVANCE_IGNORED_CHARACTERS_ENABLED))

%AutoskipTimePerEvent.value_changed.connect(_on_float_set.bind(_SETTING_AUTOSKIP_TIME_PER_EVENT))

%AutoPausesAbsolute.toggled.connect(_on_bool_set.bind(_SETTING_ABSOLUTE_AUTOPAUSES))


func _refresh() -> void:
%DefaultSpeed.value = ProjectSettings.get_setting('dialogic/text/letter_speed', 0.01)
%Skippable.button_pressed = ProjectSettings.get_setting('dialogic/text/initial_text_reveal_skippable', true)
%SkippableDelay.value = ProjectSettings.get_setting('dialogic/text/text_reveal_skip_delay', 0.1)
## BEHAVIOUR
%DefaultSpeed.value = ProjectSettings.get_setting(_SETTING_LETTER_SPEED, 0.01)

%InputAction.resource_icon = get_theme_icon(&"Mouse", &"EditorIcons")
%InputAction.set_value(ProjectSettings.get_setting(_SETTING_INPUT_ACTION, &'dialogic_default_action'))
%InputAction.get_suggestions_func = suggest_actions

%Skippable.button_pressed = ProjectSettings.get_setting(_SETTING_TEXT_REVEAL_SKIPPABLE, true)
%SkippableDelay.value = ProjectSettings.get_setting(_SETTING_TEXT_REVEAL_SKIPPABLE_DELAY, 0.1)
%AdvanceDelay.value = ProjectSettings.get_setting(_SETTING_TEXT_ADVANCE_DELAY, 0.1)

%AutoAdvance.button_pressed = ProjectSettings.get_setting('dialogic/text/autoadvance_enabled', false)
%FixedDelay.value = ProjectSettings.get_setting('dialogic/text/autoadvance_fixed_delay', 1)
%AutocolorNames.button_pressed = ProjectSettings.get_setting(_SETTING_AUTOCOLOR_NAMES, false)

var per_character_delay: float = ProjectSettings.get_setting('dialogic/text/autoadvance_per_character_delay', 0.1)
var per_word_delay: float = ProjectSettings.get_setting('dialogic/text/autoadvance_per_word_delay', 0)
%NewEvents.button_pressed = ProjectSettings.get_setting(_SETTING_SPLIT_AT_NEW_LINES, false)
%NewEventOption.select(ProjectSettings.get_setting(_SETTING_SPLIT_AT_NEW_LINES_AS, 0))

## AUTO-ADVANCE
%AutoAdvance.button_pressed = ProjectSettings.get_setting(_SETTING_AUTOADVANCE_ENABLED, false)
%FixedDelay.value = ProjectSettings.get_setting(_SETTING_AUTOADVANCE_FIXED_DELAY, 1)

var per_character_delay: float = ProjectSettings.get_setting(_SETTING_AUTOADVANCE_CHARACTER_DELAY, 0.1)
var per_word_delay: float = ProjectSettings.get_setting(_SETTING_AUTOADVANCE_WORD_DELAY, 0)
if per_character_delay == 0 and per_word_delay == 0:
_on_additional_delay_mode_item_selected(0)
elif per_word_delay == 0:
_on_additional_delay_mode_item_selected(2, per_character_delay)
else:
_on_additional_delay_mode_item_selected(1, per_word_delay)

%IgnoredCharactersEnabled.button_pressed = ProjectSettings.get_setting('dialogic/text/autoadvance_ignored_characters_enabled', true)

%IgnoredCharactersEnabled.button_pressed = ProjectSettings.get_setting(_SETTING_AUTOADVANCE_IGNORED_CHARACTERS_ENABLED, true)
var ignored_characters: String = ''
var ignored_characters_dict: Dictionary = ProjectSettings.get_setting('dialogic/text/autoadvance_ignored_characters', {})

var ignored_characters_dict: Dictionary = ProjectSettings.get_setting(_SETTING_AUTOADVANCE_IGNORED_CHARACTERS, {})
for ignored_character in ignored_characters_dict.keys():
ignored_characters += ignored_character

%IgnoredCharacters.text = ignored_characters

%AutoskipTimePerEvent.value = ProjectSettings.get_setting('dialogic/text/autoskip_time_per_event', 0.1)
## AUTO-SKIP
%AutoskipTimePerEvent.value = ProjectSettings.get_setting(_SETTING_AUTOSKIP_TIME_PER_EVENT, 0.1)

%AutocolorNames.button_pressed = ProjectSettings.get_setting('dialogic/text/autocolor_names', false)
%InputAction.resource_icon = get_theme_icon("Mouse", "EditorIcons")
%InputAction.set_value(ProjectSettings.get_setting('dialogic/text/input_action', 'dialogic_default_action'))
%InputAction.get_suggestions_func = suggest_actions

%AutoPausesAbsolute.button_pressed = ProjectSettings.get_setting('dialogic/text/absolute_autopauses', false)
%NewEvents.button_pressed = ProjectSettings.get_setting('dialogic/text/split_at_new_lines', false)
%NewEventOption.select(ProjectSettings.get_setting('dialogic/text/split_at_new_lines_as', 0))
load_autopauses(ProjectSettings.get_setting('dialogic/text/autopauses', {}))
## AUTO-PAUSES
%AutoPausesAbsolute.button_pressed = ProjectSettings.get_setting(_SETTING_ABSOLUTE_AUTOPAUSES, false)
load_autopauses(ProjectSettings.get_setting(_SETTING_AUTOPAUSES, {}))


func _about_to_close():
func _about_to_close() -> void:
save_autopauses()


func _on_Autoadvance_toggled(button_pressed):
ProjectSettings.set_setting('dialogic/text/autoadvance_enabled', button_pressed)
func _on_bool_set(button_pressed:bool, setting:String) -> void:
ProjectSettings.set_setting(setting, button_pressed)
ProjectSettings.save()


func _on_float_set(value:float, setting:String) -> void:
ProjectSettings.set_setting(setting, value)
ProjectSettings.save()


func _on_FixedDelay_value_changed(value):
ProjectSettings.set_setting('dialogic/text/autoadvance_fixed_delay', value)
#region BEHAVIOUR
################################################################################

func _on_InputAction_value_changed(property_name:String, value:String) -> void:
ProjectSettings.set_setting(_SETTING_INPUT_ACTION, value)
ProjectSettings.save()

func suggest_actions(search:String) -> Dictionary:
var suggs := {}
for prop in ProjectSettings.get_property_list():
if prop.name.begins_with('input/') and not prop.name.begins_with('input/ui_') :
suggs[prop.name.trim_prefix('input/')] = {'value':prop.name.trim_prefix('input/')}
return suggs


func _on_new_event_option_item_selected(index:int) -> void:
ProjectSettings.set_setting(_SETTING_SPLIT_AT_NEW_LINES_AS, index)
ProjectSettings.save()

#endregion

#region AUTO-ADVANCE
################################################################################

func _on_additional_delay_mode_item_selected(index:int, delay:float=-1) -> void:
%AdditionalDelayMode.selected = index
match index:
0: # NONE
%AdditionalDelay.hide()
%AutoadvanceIgnoreCharacters.hide()
ProjectSettings.set_setting('dialogic/text/autoadvance_per_word_delay', 0)
ProjectSettings.set_setting('dialogic/text/autoadvance_per_character_delay', 0)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_WORD_DELAY, 0)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_CHARACTER_DELAY, 0)
1: # PER WORD
%AdditionalDelay.show()
%AutoadvanceIgnoreCharacters.hide()
if delay != -1:
%AdditionalDelay.value = delay
else:
ProjectSettings.set_setting('dialogic/text/autoadvance_per_word_delay', %AdditionalDelay.value)
ProjectSettings.set_setting('dialogic/text/autoadvance_per_character_delay', 0)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_WORD_DELAY, %AdditionalDelay.value)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_CHARACTER_DELAY, 0)
2: # PER CHARACTER
%AdditionalDelay.show()
%AutoadvanceIgnoreCharacters.show()
if delay != -1:
%AdditionalDelay.value = delay
else:
ProjectSettings.set_setting('dialogic/text/autoadvance_per_character_delay', %AdditionalDelay.value)
ProjectSettings.set_setting('dialogic/text/autoadvance_per_word_delay', 0)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_CHARACTER_DELAY, %AdditionalDelay.value)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_WORD_DELAY, 0)
ProjectSettings.save()


func _on_additional_delay_value_changed(value:float) -> void:
match %AdditionalDelayMode.selected:
0: # NONE
ProjectSettings.set_setting('dialogic/text/autoadvance_per_character_delay', 0)
ProjectSettings.set_setting('dialogic/text/autoadvance_per_word_delay', 0)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_CHARACTER_DELAY, 0)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_WORD_DELAY, 0)
1: # PER WORD
ProjectSettings.set_setting('dialogic/text/autoadvance_per_word_delay', value)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_WORD_DELAY, value)
2: # PER CHARACTER
ProjectSettings.set_setting('dialogic/text/autoadvance_per_character_delay', value)
ProjectSettings.save()


func _on_IgnoredCharactersEnabled_toggled(button_pressed):
ProjectSettings.set_setting('dialogic/text/autoadvance_ignored_characters_enabled', button_pressed)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_CHARACTER_DELAY, value)
ProjectSettings.save()


func _on_IgnoredCharacters_text_changed(text_input):
ProjectSettings.set_setting('dialogic/text/autoadvance_ignored_characters', DialogicUtil.str_to_hash_set(text_input))
ProjectSettings.save()


func _on_Skippable_toggled(button_pressed):
ProjectSettings.set_setting('dialogic/text/initial_text_reveal_skippable', button_pressed)
ProjectSettings.save()


func _on_skippable_delay_value_changed(value: float) -> void:
ProjectSettings.set_setting('dialogic/text/text_reveal_skip_delay', value)
ProjectSettings.save()


func _on_DefaultSpeed_value_changed(value):
ProjectSettings.set_setting('dialogic/text/letter_speed', value)
ProjectSettings.save()

func _on_AutoskipTimePerEvent_value_changed(value: float) -> void:
ProjectSettings.set_setting('dialogic/text/autoskip_time_per_event', value)
ProjectSettings.save()

func _on_InputAction_value_changed(property_name, value):
ProjectSettings.set_setting('dialogic/text/input_action', value)
ProjectSettings.set_setting(_SETTING_AUTOADVANCE_IGNORED_CHARACTERS, DialogicUtil.str_to_hash_set(text_input))
ProjectSettings.save()

#endregion

func suggest_actions(search:String) -> Dictionary:
var suggs := {}
for prop in ProjectSettings.get_property_list():
if prop.name.begins_with('input/'):
suggs[prop.name.trim_prefix('input/')] = {'value':prop.name.trim_prefix('input/')}
return suggs


func _on_AutocolorNames_toggled(button_pressed:bool) -> void:
ProjectSettings.set_setting('dialogic/text/autocolor_names', button_pressed)
ProjectSettings.save()

## AUTO-PAUSES
################################################################################

func load_autopauses(dictionary:Dictionary) -> void:
for i in %AutoPauseSets.get_children():
Expand All @@ -159,21 +197,20 @@ func load_autopauses(dictionary:Dictionary) -> void:
add_autopause_set(i, dictionary[i])



func save_autopauses() -> void:
var dictionary := {}
for i in autopause_sets:
if is_instance_valid(autopause_sets[i].time):
dictionary[autopause_sets[i].text.text] = autopause_sets[i].time.value
ProjectSettings.set_setting('dialogic/text/autopauses', dictionary)
ProjectSettings.set_setting(_SETTING_AUTOPAUSES, dictionary)
ProjectSettings.save()


func _on_add_autopauses_set_pressed():
func _on_add_autopauses_set_pressed() -> void:
add_autopause_set('', 0.1)


func add_autopause_set(text:String, time:float) -> void:
func add_autopause_set(text: String, time: float) -> void:
var info := {}
var line_edit := LineEdit.new()
line_edit.size_flags_horizontal = Control.SIZE_EXPAND_FILL
Expand All @@ -189,30 +226,15 @@ func add_autopause_set(text:String, time:float) -> void:
%AutoPauseSets.add_child(spin_box)

var remove_btn := Button.new()
remove_btn.icon = get_theme_icon('Remove', 'EditorIcons')
remove_btn.icon = get_theme_icon(&'Remove', &'EditorIcons')
remove_btn.pressed.connect(_on_remove_autopauses_set_pressed.bind(len(autopause_sets)))
info['delete'] = remove_btn
%AutoPauseSets.add_child(remove_btn)
autopause_sets[len(autopause_sets)] = info


func _on_remove_autopauses_set_pressed(index:int) -> void:
func _on_remove_autopauses_set_pressed(index: int) -> void:
for key in autopause_sets[index]:
autopause_sets[index][key].queue_free()
autopause_sets.erase(index)


func _on_auto_pauses_absolute_toggled(button_pressed:bool) -> void:
ProjectSettings.set_setting('dialogic/text/absolute_autopauses', button_pressed)
ProjectSettings.save()


func _on_new_events_toggled(button_pressed:bool) -> void:
ProjectSettings.set_setting('dialogic/text/split_at_new_lines', button_pressed)
ProjectSettings.save()


func _on_new_event_option_item_selected(index:int) -> void:
ProjectSettings.set_setting('dialogic/text/split_at_new_lines_as', index)
ProjectSettings.save()

Loading

0 comments on commit f3b0604

Please sign in to comment.