Skip to content

Commit

Permalink
Implement User-Configurable Delays for Line Features
Browse files Browse the repository at this point in the history
This commit introduces user-configurable settings for all delay types, with separate levels for critical and informational features. To avoid an excessive number of settings, individual delays for each category are grouped as items within their corresponding setting.

Additionally, a function has been added to the `LineFeature` class constructor to read these delay settings from user configuration. This function is registered to be called whenever a user modifies any of the delay values, effectively reloading the settings.
  • Loading branch information
ramoncorominas committed Feb 17, 2024
1 parent c3be4b3 commit ebf3cb0
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ const signalFeatureBase: IConfigurationPropertySchema = {
announcement: 'auto'
}
};
const signalDelayBase: IConfigurationPropertySchema = {
type: 'number',
minimum: 0,
maximum: 5000,
default: 0,
tags: ['accessibility'],
};
const signalFeatureDelaysBase: IConfigurationPropertySchema = {
type: 'object',
tags: ['accessibility'],
additionalProperties: false,
};

export const announcementFeatureBase: IConfigurationPropertySchema = {
'type': 'string',
Expand Down Expand Up @@ -280,6 +292,62 @@ const configuration: IConfigurationNode = {
'default': false,
tags: ['accessibility']
},
'accessibility.signals.lineFeatureDelays.critical': {
...signalFeatureDelaysBase,
'description': localize('accessibility.signals.lineFeatureDelays.critical', "Delays applied to accessibility signals when the active line has a critical feature (e.g. error, warning)."),
default: {
soundLineDelay: 0,
soundInlineDelay: 300,
announcementLineDelay: 300,
announcementInlineDelay: 600
},
'properties': {
'soundLineDelay': {
...signalDelayBase,
'description': localize('accessibility.signals.lineFeatureDelays.critical.soundLineDelay', "Delay for sounds when moving to a line with critical features."),
},
'soundInlineDelay': {
...signalDelayBase,
'description': localize('accessibility.signals.lineFeatureDelays.critical.soundInlineDelay', "Delay for sounds when moving within a line with critical features."),
},
'announcementLineDelay': {
...signalDelayBase,
'description': localize('accessibility.signals.lineFeatureDelays.critical.announcementLineDelay', "Delay for announcements when moving to a line with critical features."),
},
'announcementInlineDelay': {
...signalDelayBase,
'description': localize('accessibility.signals.lineFeatureDelays.critical.announcementInlineDelay', "Delay for announcements when moving within a line with critical features."),
},
},
},
'accessibility.signals.lineFeatureDelays.informational': {
...signalFeatureDelaysBase,
'description': localize('accessibility.signals.lineFeatureDelays.informational', "Delays applied to accessibility signals when the active line has an informational feature (e.g. breakpoint, folded area)."),
'default': {
soundLineDelay: 300,
soundInlineDelay: 600,
announcementLineDelay: 600,
announcementInlineDelay: 1200
},
'properties': {
'soundLineDelay': {
...signalDelayBase,
'description': localize('accessibility.signals.lineFeatureDelays.informational.soundLineDelay', "Delay for sounds when moving to a line with informational features."),
},
'soundInlineDelay': {
...signalDelayBase,
'description': localize('accessibility.signals.lineFeatureDelays.informational.soundInlineDelay', "Delay for sounds when moving within a line with informational features."),
},
'announcementLineDelay': {
...signalDelayBase,
'description': localize('accessibility.signals.lineFeatureDelays.informational.announcementLineDelay', "Delay for announcements when moving to a line with informational features."),
},
'announcementInlineDelay': {
...signalDelayBase,
'description': localize('accessibility.signals.lineFeatureDelays.informational.announcementInlineDelay', "Delay for announcements when moving within a line with informational features."),
},
},
},
'accessibility.signals.lineHasBreakpoint': {
...signalFeatureBase,
'description': localize('accessibility.signals.lineHasBreakpoint', "Plays a signal when the active line has a breakpoint."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ export class SignalLineFeatureContribution
}
);

this._register(this._configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('accessibility.signals.lineFeatureDelays')) {
this.features.forEach(f => f.readDelaysFromSettings(this._configurationService));
}
}));

this._register(
autorun(reader => {
/** @description updateSignalsEnabled */
Expand Down Expand Up @@ -204,6 +210,7 @@ interface LineFeature {
editor: ICodeEditor,
model: ITextModel
): IObservable<LineFeatureState>;
readDelaysFromSettings(configurationService: IConfigurationService): void;
trackLineChanged(position: Position): void;
getDelay(modality: SignalModality): number;
}
Expand All @@ -213,12 +220,11 @@ interface LineFeatureState {
}

type DelayType = {
line: number;
inline: number;
lineDelay: number;
inlineDelay: number;
};

abstract class BaseLineFeature implements LineFeature {
// mandatory properties of the original LineFeature interface
abstract signal: AccessibilitySignal;
abstract getObservableState(
editor: ICodeEditor,
Expand All @@ -227,8 +233,21 @@ abstract class BaseLineFeature implements LineFeature {

// Holds the current delay values associated with this feature
protected _modalityDelays: Map<SignalModality, DelayType> = new Map();
protected setModalityDelays(modality: SignalModality, lineDelay: number, inlineDelay: number) {
this._modalityDelays.set(modality, { line: lineDelay, inline: inlineDelay });
protected setModalityDelays(modality: SignalModality, lineDelay: number | undefined, inlineDelay: number | undefined) {
this._modalityDelays.set(modality, { lineDelay: lineDelay || 0, inlineDelay: inlineDelay || 0 });
}
public readDelaysFromSettings(configurationService: IConfigurationService) {
// set default delays to "info" feature type (longer delays)
this.setModalityDelays(
SignalModality.Sound,
configurationService.getValue('accessibility.signals.lineFeatureDelays.informational.soundLineDelay'),
configurationService.getValue('accessibility.signals.lineFeatureDelays.informational.soundInlineDelay')
);
this.setModalityDelays(
SignalModality.Announcement,
configurationService.getValue('accessibility.signals.lineFeatureDelays.informational.announcementLineDelay'),
configurationService.getValue('accessibility.signals.lineFeatureDelays.informational.announcementInlineDelay')
);
}

protected _previousLine: number = 0;
Expand All @@ -238,18 +257,11 @@ abstract class BaseLineFeature implements LineFeature {
this._previousLine = position.lineNumber;
}

constructor() {
// set default delays to "info" feature type (longer delays)
// TODO: Retrieve values from user-configurable settings
this.setModalityDelays(SignalModality.Sound, 300, 600);
this.setModalityDelays(SignalModality.Announcement, 600, 1500);
}

public getDelay(modality: SignalModality): number {
let minDelay = Infinity;
for (const [key, delayObj] of this._modalityDelays) {
if ((modality & key) !== 0) {
const delay = this._lineChanged ? delayObj.line : delayObj.inline;
const delay = this._lineChanged ? delayObj.lineDelay : delayObj.inlineDelay;
if (delay < minDelay) {
minDelay = delay;
}
Expand All @@ -261,17 +273,28 @@ abstract class BaseLineFeature implements LineFeature {

class MarkerLineFeature extends BaseLineFeature implements LineFeature {
public readonly debounceWhileTyping = true;
public override readDelaysFromSettings(configurationService: IConfigurationService) {
// set delays to "critical" feature type (shorter delays)
this.setModalityDelays(
SignalModality.Sound,
configurationService.getValue('accessibility.signals.lineFeatureDelays.critical.soundLineDelay'),
configurationService.getValue('accessibility.signals.lineFeatureDelays.critical.soundInlineDelay')
);
this.setModalityDelays(
SignalModality.Announcement,
configurationService.getValue('accessibility.signals.lineFeatureDelays.critical.announcementLineDelay'),
configurationService.getValue('accessibility.signals.lineFeatureDelays.critical.announcementInlineDelay')
);
}

constructor(
public readonly signal: AccessibilitySignal,
private readonly severity: MarkerSeverity,
@IMarkerService private readonly markerService: IMarkerService,

@IConfigurationService private readonly configurationService: IConfigurationService,
) {
super();
// TODO: Retrieve values from user-configurable settings
this.setModalityDelays(SignalModality.Sound, 0, 300);
this.setModalityDelays(SignalModality.Announcement, 300, 600);
this.readDelaysFromSettings(this.configurationService);
}

getObservableState(editor: ICodeEditor, model: ITextModel): IObservable<LineFeatureState> {
Expand All @@ -298,8 +321,9 @@ class MarkerLineFeature extends BaseLineFeature implements LineFeature {
class FoldedAreaLineFeature extends BaseLineFeature implements LineFeature {
public readonly signal = AccessibilitySignal.foldedArea;

constructor() {
constructor(@IConfigurationService private readonly configurationService: IConfigurationService) {
super();
this.readDelaysFromSettings(this.configurationService);
}

getObservableState(editor: ICodeEditor, model: ITextModel): IObservable<LineFeatureState> {
Expand Down Expand Up @@ -329,8 +353,12 @@ class FoldedAreaLineFeature extends BaseLineFeature implements LineFeature {
class BreakpointLineFeature extends BaseLineFeature implements LineFeature {
public readonly signal = AccessibilitySignal.break;

constructor(@IDebugService private readonly debugService: IDebugService) {
constructor(@
IDebugService private readonly debugService: IDebugService,
@IConfigurationService private readonly configurationService: IConfigurationService
) {
super();
this.readDelaysFromSettings(this.configurationService);
}

getObservableState(editor: ICodeEditor, model: ITextModel): IObservable<LineFeatureState> {
Expand Down

0 comments on commit ebf3cb0

Please sign in to comment.