import { Component, Input, Output, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { animate, state, style, transition, trigger } from '@angular/animations'; import { DelayMacroAction, KeyMacroAction, KeyModifiers, MacroAction, MouseButtons, MouseButtonMacroAction, MoveMouseMacroAction, ScrollMouseMacroAction, TextMacroAction } from 'uhk-common'; import { MapperService } from '../../../services/mapper.service'; @Component({ animations: [ trigger('toggler', [ state('inactive', style({ height: '0px' })), state('active', style({ height: '*' })), transition('inactive <=> active', animate('500ms ease-out')) ]) ], selector: 'macro-item', templateUrl: './macro-item.component.html', styleUrls: ['./macro-item.component.scss'], host: { 'class': 'macro-item' } }) export class MacroItemComponent implements OnInit, OnChanges { @Input() macroAction: MacroAction; @Input() editable: boolean; @Input() deletable: boolean; @Input() movable: boolean; @Output() save = new EventEmitter(); @Output() cancel = new EventEmitter(); @Output() edit = new EventEmitter(); @Output() delete = new EventEmitter(); title: string; iconName: string; editing: boolean; newItem: boolean = false; overflow = 'hidden'; constructor(private mapper: MapperService) { } ngOnInit() { this.updateView(); if (!this.macroAction) { this.editing = true; this.newItem = true; this.overflow = 'visible'; } } ngOnChanges(changes: SimpleChanges) { if (changes['macroAction']) { this.updateView(); } } saveEditedAction(editedAction: MacroAction): void { this.macroAction = editedAction; this.editing = false; this.overflow = 'hidden'; this.updateView(); this.save.emit(editedAction); } editAction(): void { if (!this.editable || this.editing) { this.cancelEdit(); return; } this.editing = true; this.edit.emit(); this.setOverflow('visible'); } cancelEdit(): void { this.editing = false; this.overflow = 'hidden'; this.cancel.emit(); } deleteAction(): void { this.delete.emit(); } private updateView(): void { if (!this.macroAction) { this.title = 'New macro action'; } else if (this.macroAction instanceof DelayMacroAction) { // Delay this.iconName = 'clock'; const action: DelayMacroAction = this.macroAction as DelayMacroAction; const delay = action.delay > 0 ? action.delay / 1000 : 0; this.title = `Delay of ${delay}s`; } else if (this.macroAction instanceof TextMacroAction) { // Write text const action: TextMacroAction = this.macroAction as TextMacroAction; this.iconName = 'font'; this.title = `Write text: ${action.text}`; } else if (this.macroAction instanceof KeyMacroAction) { // Key pressed/held/released const action: KeyMacroAction = this.macroAction as KeyMacroAction; this.setKeyActionContent(action); } else if (this.macroAction instanceof MouseButtonMacroAction) { // Mouse button clicked/held/released const action: MouseButtonMacroAction = this.macroAction as MouseButtonMacroAction; this.setMouseButtonActionContent(action); } else if (this.macroAction instanceof MoveMouseMacroAction || this.macroAction instanceof ScrollMouseMacroAction) { // Mouse moved or scrolled this.setMouseMoveScrollActionContent(this.macroAction); } else { this.title = this.macroAction.constructor.name; } } private setKeyActionContent(action: KeyMacroAction): void { if (!action.hasScancode() && !action.hasModifiers()) { this.title = 'Invalid keypress'; return; } if (action.isTapAction()) { // Tap key this.iconName = 'hand-pointer'; this.title = 'Tap key: '; } else if (action.isPressAction()) { // Press key this.iconName = 'hand-rock'; this.title = 'Press key: '; } else if (action.isReleaseAction()) { // Release key this.iconName = 'hand-paper'; this.title = 'Release key: '; } if (action.hasScancode()) { const scancode: string = (this.mapper.scanCodeToText(action.scancode, action.type) || ['Unknown']).join(' '); if (scancode) { this.title += scancode; } } if (action.hasModifiers()) { // Tap/press/release modifiers for (let i = KeyModifiers.leftCtrl; i <= KeyModifiers.rightGui; i <<= 1) { if (action.isModifierActive(i)) { this.title += ' ' + this.mapper.getOsSpecificModifierTextByValue(i); } } } } private setMouseMoveScrollActionContent(action: MacroAction): void { let typedAction: any; if (action instanceof MoveMouseMacroAction) { // Move mouse pointer this.iconName = 'mouse-pointer'; this.title = 'Move pointer'; typedAction = this.macroAction as MoveMouseMacroAction; } else { // Scroll mouse this.iconName = 'mouse-pointer'; this.title = 'Scroll'; typedAction = this.macroAction as ScrollMouseMacroAction; } let needAnd: boolean; if (Math.abs(typedAction.x) !== 0) { this.title += ` by ${Math.abs(typedAction.x)}px ${typedAction.x > 0 ? 'rightward' : 'leftward'}`; needAnd = true; } if (Math.abs(typedAction.y) !== 0) { this.title += ` ${needAnd ? 'and' : 'by'} ${Math.abs(typedAction.y)}px ${typedAction.y > 0 ? 'downward' : 'upward'}`; } } private setMouseButtonActionContent(action: MouseButtonMacroAction): void { // Press/hold/release mouse buttons if (action.isOnlyClickAction()) { this.iconName = 'mouse-pointer'; this.title = 'Click mouse button: '; } else if (action.isOnlyHoldAction()) { this.iconName = 'hand-rock'; this.title = 'Hold mouse button: '; } else if (action.isOnlyReleaseAction()) { this.iconName = 'hand-paper'; this.title = 'Release mouse button: '; } const selectedButtons: boolean[] = action.getMouseButtons(); const selectedButtonLabels: string[] = []; selectedButtons.forEach((isSelected, idx) => { if (isSelected && MouseButtons[idx]) { selectedButtonLabels.push(MouseButtons[idx]); } }); this.title += selectedButtonLabels.join(', '); } private setOverflow(value: string): void { // tslint:disable: align setTimeout(() => { this.overflow = value; }, 600); // tslint:enable: align } }