/** * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose */ import { ButtonsType, ModifiersKeys } from './input/input-observer'; import { interpolate, stringToWords } from './string'; export { Binding }; interface Binding { triggers: Binding.Trigger[] action: string description: string } function Binding(triggers: Binding.Trigger[], action = '', description = '') { return Binding.create(triggers, action, description); } namespace Binding { export function create(triggers: Trigger[], action = '', description = ''): Binding { return { triggers, action, description }; } export const Empty: Binding = { triggers: [], action: '', description: '' }; export function isEmpty(binding: Binding) { return binding.triggers.length === 0 || binding.triggers.every(t => t.buttons === undefined && t.modifiers === undefined); } export function match(binding: Binding, buttons: ButtonsType, modifiers: ModifiersKeys) { return binding.triggers.some(t => Trigger.match(t, buttons, modifiers)); } export function formatTriggers(binding: Binding) { return binding.triggers.map(Trigger.format).join(' or '); } export function format(binding: Binding, name = '') { const help = binding.description || stringToWords(name); return interpolate(help, { triggers: '' + formatTriggers(binding) + '' }); } export interface Trigger { buttons?: ButtonsType, modifiers?: ModifiersKeys } export function Trigger(buttons?: ButtonsType, modifiers?: ModifiersKeys) { return Trigger.create(buttons, modifiers); } export namespace Trigger { export function create(buttons?: ButtonsType, modifiers?: ModifiersKeys): Trigger { return { buttons, modifiers }; } export const Empty: Trigger = {}; export function match(trigger: Trigger, buttons: ButtonsType, modifiers: ModifiersKeys): boolean { const { buttons: b, modifiers: m } = trigger; return b !== undefined && (b === buttons || ButtonsType.has(b, buttons)) && (!m || ModifiersKeys.areEqual(m, modifiers)); } export function format(trigger: Trigger) { const s: string[] = []; const b = formatButtons(trigger.buttons); if (b) s.push(b); const m = formatModifiers(trigger.modifiers); if (m) s.push(m); return s.join(' + '); } } } const B = ButtonsType; function formatButtons(buttons?: ButtonsType) { const s: string[] = []; if (buttons === undefined) { s.push('any mouse button'); } else if (buttons === 0) { s.push('mouse hover'); } else { if (B.has(buttons, B.Flag.Primary)) s.push('left mouse button'); if (B.has(buttons, B.Flag.Secondary)) s.push('right mouse button'); if (B.has(buttons, B.Flag.Auxilary)) s.push('wheel/middle mouse button'); if (B.has(buttons, B.Flag.Forth)) s.push('three fingers'); } return s.join(' + '); } function formatModifiers(modifiers?: ModifiersKeys, verbose?: boolean) { const s: string[] = []; if (modifiers) { if (modifiers.alt) s.push('alt key'); if (modifiers.control) s.push('control key'); if (modifiers.meta) s.push('meta/command key'); if (modifiers.shift) s.push('shift key'); if (verbose && s.length === 0) s.push('no key'); } else { if (verbose) s.push('any key'); } return s.join(' + '); }