Files
agent/packages/uhk-web/src/app/components/macro/item/macro-item.component.ts

219 lines
7.2 KiB
TypeScript

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<MacroAction>();
@Output() cancel = new EventEmitter<void>();
@Output() edit = new EventEmitter<void>();
@Output() delete = new EventEmitter<void>();
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
}
}