diff --git a/shared/src/components/macro/action-editor/macro-action-editor.component.ts b/shared/src/components/macro/action-editor/macro-action-editor.component.ts index 75f4ce3a..95e10e8a 100644 --- a/shared/src/components/macro/action-editor/macro-action-editor.component.ts +++ b/shared/src/components/macro/action-editor/macro-action-editor.component.ts @@ -1,12 +1,18 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { - EditableMacroAction, MacroAction, + DelayMacroAction, + KeyMacroAction, + ScrollMouseMacroAction, + MoveMouseMacroAction, + MouseButtonMacroAction, TextMacroAction, - macroActionType + macroActionType, + Helper as MacroActionHelper } from '../../../config-serializer/config-items/macro-action'; -import { MacroKeyTabComponent } from './tab/key'; +import { MacroDelayTabComponent, MacroMouseTabComponent, MacroKeyTabComponent, MacroTextTabComponent } from './tab'; +import { KeystrokeAction } from '../../../config-serializer/config-items/key-action'; enum TabName { Keypress, @@ -27,34 +33,35 @@ export class MacroActionEditorComponent implements OnInit { @Output() save = new EventEmitter(); @Output() cancel = new EventEmitter(); - @ViewChild('tab') selectedTab: any; + @ViewChild('tab') selectedTab: MacroTextTabComponent | MacroKeyTabComponent | MacroMouseTabComponent | MacroDelayTabComponent; - editableMacroAction: EditableMacroAction; + editableMacroAction: MacroAction; activeTab: TabName; /* tslint:disable:variable-name: It is an enum type. So it can start with uppercase. */ TabName = TabName; /* tslint:enable:variable-name */ ngOnInit() { - const macroAction: MacroAction = this.macroAction ? this.macroAction : new TextMacroAction(); - this.editableMacroAction = new EditableMacroAction(macroAction.toJsonObject()); + this.updateEditableMacroAction(); const tab: TabName = this.getTabName(this.editableMacroAction); this.activeTab = tab; } + ngOnChanges() { + this.ngOnInit(); + } + onCancelClick(): void { this.cancel.emit(); } onSaveClick(): void { try { - const action = this.editableMacroAction; - if (action.isKeyAction()) { - // Could updating the saved keys be done in a better way? - const tab = this.selectedTab as MacroKeyTabComponent; - action.fromKeyAction(tab.getKeyAction()); - } - this.save.emit(action.toClass()); + // TODO: Refactor after getKeyMacroAction has been added to all tabs + const action = this.selectedTab instanceof MacroKeyTabComponent ? + this.selectedTab.getKeyMacroAction() : + this.selectedTab.macroAction; + this.save.emit(action); } catch (e) { // TODO: show error dialog console.error(e); @@ -63,43 +70,31 @@ export class MacroActionEditorComponent implements OnInit { selectTab(tab: TabName): void { this.activeTab = tab; - this.editableMacroAction.macroActionType = this.getTabMacroActionType(tab); - } - - getTabName(action: EditableMacroAction): TabName { - switch (action.macroActionType) { - // Delay action - case macroActionType.DelayMacroAction: - return TabName.Delay; - // Text action - case macroActionType.TextMacroAction: - return TabName.Text; - // Keypress actions - case macroActionType.KeyMacroAction: - return TabName.Keypress; - // Mouse actions - case macroActionType.MouseButtonMacroAction: - case macroActionType.MoveMouseMacroAction: - case macroActionType.ScrollMouseMacroAction: - return TabName.Mouse; - default: - return TabName.Keypress; + if (tab === this.getTabName(this.macroAction)) { + this.updateEditableMacroAction(); + } else { + this.editableMacroAction = undefined; } } - getTabMacroActionType(tab: TabName): string { - switch (tab) { - case TabName.Delay: - return macroActionType.DelayMacroAction; - case TabName.Keypress: - return macroActionType.KeyMacroAction; - case TabName.Mouse: - return macroActionType.MouseButtonMacroAction; - case TabName.Text: - return macroActionType.TextMacroAction; - default: - throw new Error('Could not get macro action type'); + getTabName(action: MacroAction): TabName { + if (action instanceof DelayMacroAction) { + return TabName.Delay; + } else if (action instanceof TextMacroAction) { + return TabName.Text; + } else if (action instanceof KeyMacroAction) { + return TabName.Keypress; + } else if (action instanceof MouseButtonMacroAction || + action instanceof MoveMouseMacroAction || + action instanceof ScrollMouseMacroAction) { + return TabName.Mouse; } + return undefined; + } + + private updateEditableMacroAction() { + const macroAction: MacroAction = this.macroAction ? this.macroAction : new TextMacroAction(); + this.editableMacroAction = MacroActionHelper.createMacroAction(macroAction); } } diff --git a/shared/src/components/macro/action-editor/tab/delay/macro-delay.component.ts b/shared/src/components/macro/action-editor/tab/delay/macro-delay.component.ts index 0d779e52..dc6d8da4 100644 --- a/shared/src/components/macro/action-editor/tab/delay/macro-delay.component.ts +++ b/shared/src/components/macro/action-editor/tab/delay/macro-delay.component.ts @@ -7,7 +7,7 @@ import { ViewChild } from '@angular/core'; -import { EditableMacroAction } from '../../../../../config-serializer/config-items/macro-action'; +import { DelayMacroAction } from '../../../../../config-serializer/config-items/macro-action'; const INITIAL_DELAY = 0.5; // In seconds @@ -19,7 +19,7 @@ const INITIAL_DELAY = 0.5; // In seconds changeDetection: ChangeDetectionStrategy.OnPush }) export class MacroDelayTabComponent implements OnInit { - @Input() macroAction: EditableMacroAction; + @Input() macroAction: DelayMacroAction; @ViewChild('macroDelayInput') input: ElementRef; delay: number; @@ -28,6 +28,9 @@ export class MacroDelayTabComponent implements OnInit { constructor() { } ngOnInit() { + if (!this.macroAction) { + this.macroAction = new DelayMacroAction(); + } this.delay = this.macroAction.delay > 0 ? this.macroAction.delay / 1000 : INITIAL_DELAY; } diff --git a/shared/src/components/macro/action-editor/tab/key/macro-key.component.ts b/shared/src/components/macro/action-editor/tab/key/macro-key.component.ts index 5d980cd9..3073a36e 100644 --- a/shared/src/components/macro/action-editor/tab/key/macro-key.component.ts +++ b/shared/src/components/macro/action-editor/tab/key/macro-key.component.ts @@ -1,7 +1,7 @@ import { Component, Input, OnInit, ViewChild } from '@angular/core'; -import { KeyAction } from '../../../../../config-serializer/config-items/key-action'; -import { EditableMacroAction, MacroSubAction } from '../../../../../config-serializer/config-items/macro-action'; +import { KeyAction, KeystrokeAction } from '../../../../../config-serializer/config-items/key-action'; +import { KeyMacroAction, MacroSubAction } from '../../../../../config-serializer/config-items/macro-action'; import { KeypressTabComponent } from '../../../../popover/tab'; import { Tab } from '../../../../popover/tab'; @@ -21,7 +21,7 @@ enum TabName { host: { 'class': 'macro__mouse' } }) export class MacroKeyTabComponent implements OnInit { - @Input() macroAction: EditableMacroAction; + @Input() macroAction: KeyMacroAction; @ViewChild('tab') selectedTab: Tab; @ViewChild('keypressTab') keypressTab: KeypressTabComponent; @@ -29,24 +29,26 @@ export class MacroKeyTabComponent implements OnInit { TabName = TabName; /* tslint:enable:variable-name */ activeTab: TabName; - defaultKeyAction: KeyAction; + defaultKeyAction: KeystrokeAction; ngOnInit() { - this.defaultKeyAction = this.macroAction.toKeystrokeAction(); + if (!this.macroAction) { + this.macroAction = new KeyMacroAction(); + } + this.defaultKeyAction = new KeystrokeAction(this.macroAction); this.selectTab(this.getTabName(this.macroAction)); } selectTab(tab: TabName): void { this.activeTab = tab; - this.macroAction.action = this.getActionType(tab); } - getTabName(action: EditableMacroAction): TabName { - if (!action.action || action.isOnlyPressAction()) { + getTabName(macroAction: KeyMacroAction): TabName { + if (!macroAction.action) { return TabName.Keypress; - } else if (action.isOnlyHoldAction()) { + } else if (macroAction.action === MacroSubAction.hold) { return TabName.Hold; - } else if (action.isOnlyReleaseAction()) { + } else if (macroAction.action === MacroSubAction.release) { return TabName.Release; } } @@ -64,8 +66,10 @@ export class MacroKeyTabComponent implements OnInit { } } - getKeyAction(): KeyAction { - return this.keypressTab.toKeyAction(); + getKeyMacroAction(): KeyMacroAction { + const keyMacroAction = Object.assign(new KeyMacroAction(), this.keypressTab.toKeyAction()); + keyMacroAction.action = this.getActionType(this.activeTab); + return keyMacroAction; } } diff --git a/shared/src/components/macro/action-editor/tab/mouse/macro-mouse.component.html b/shared/src/components/macro/action-editor/tab/mouse/macro-mouse.component.html index 6419fce3..d4c1ecb4 100644 --- a/shared/src/components/macro/action-editor/tab/mouse/macro-mouse.component.html +++ b/shared/src/components/macro/action-editor/tab/mouse/macro-mouse.component.html @@ -40,11 +40,11 @@
- pixels + pixels
- pixels + pixels
@@ -54,11 +54,11 @@
- pixels + pixels
- pixels + pixels
@@ -68,10 +68,10 @@

Release mouse button

- \ No newline at end of file + diff --git a/shared/src/components/macro/action-editor/tab/mouse/macro-mouse.component.ts b/shared/src/components/macro/action-editor/tab/mouse/macro-mouse.component.ts index 7f5691d6..a395d488 100644 --- a/shared/src/components/macro/action-editor/tab/mouse/macro-mouse.component.ts +++ b/shared/src/components/macro/action-editor/tab/mouse/macro-mouse.component.ts @@ -1,8 +1,12 @@ import { Component, Input, OnInit, ViewChild } from '@angular/core'; -import { EditableMacroAction, MacroSubAction, macroActionType } from '../../../../../config-serializer/config-items/macro-action'; +import { + MouseButtonMacroAction, MoveMouseMacroAction, ScrollMouseMacroAction, MacroSubAction, macroActionType +} from '../../../../../config-serializer/config-items/macro-action'; import { Tab } from '../../../../popover/tab'; +type MouseMacroAction = MouseButtonMacroAction | MoveMouseMacroAction | ScrollMouseMacroAction; + enum TabName { Move, Scroll, @@ -21,7 +25,7 @@ enum TabName { host: { 'class': 'macro__mouse' } }) export class MacroMouseTabComponent implements OnInit { - @Input() macroAction: EditableMacroAction; + @Input() macroAction: MouseMacroAction; @ViewChild('tab') selectedTab: Tab; /* tslint:disable:variable-name: It is an enum type. So it can start with uppercase. */ @@ -37,25 +41,46 @@ export class MacroMouseTabComponent implements OnInit { } ngOnInit() { + if (!this.macroAction) { + this.macroAction = new MouseButtonMacroAction(); + this.macroAction.action = MacroSubAction.press; + } const tabName = this.getTabName(this.macroAction); this.selectTab(tabName); const buttonActions = [TabName.Click, TabName.Hold, TabName.Release]; if (buttonActions.includes(this.activeTab)) { - this.selectedButtons = this.macroAction.getMouseButtons(); + this.selectedButtons = (this.macroAction).getMouseButtons(); } } + ngOnChanges() { + this.ngOnInit(); + } + selectTab(tab: TabName): void { this.activeTab = tab; - this.macroAction.macroActionType = this.getMacroActionType(tab); - if (this.macroAction.macroActionType === macroActionType.MouseButtonMacroAction) { - this.macroAction.action = this.getAction(tab); + + if (tab === this.getTabName(this.macroAction)) { + return; + } + + switch (tab) { + case TabName.Scroll: + this.macroAction = new ScrollMouseMacroAction(); + break; + case TabName.Move: + this.macroAction = new MoveMouseMacroAction(); + break; + default: + this.macroAction = new MouseButtonMacroAction(); + this.macroAction.action = this.getAction(tab); + break; } } setMouseClick(index: number): void { this.selectedButtons[index] = !this.selectedButtons[index]; - this.macroAction.setMouseButtons(this.selectedButtons); + (this.macroAction).setMouseButtons(this.selectedButtons); } hasButton(index: number): boolean { @@ -71,35 +96,25 @@ export class MacroMouseTabComponent implements OnInit { case TabName.Release: return MacroSubAction.release; default: - throw new Error('Invalid tab name'); + throw new Error(`Invalid tab name: ${TabName[tab]}`); } } - getTabName(action: EditableMacroAction): TabName { - if (action.macroActionType === macroActionType.MouseButtonMacroAction) { + getTabName(action: MouseMacroAction): TabName { + if (action instanceof MouseButtonMacroAction) { if (!action.action || action.isOnlyPressAction()) { return TabName.Click; - } else if (action.isOnlyPressAction()) { + } else if (action.isOnlyHoldAction()) { return TabName.Hold; } else if (action.isOnlyReleaseAction()) { return TabName.Release; } - } else if (action.macroActionType === macroActionType.MoveMouseMacroAction) { + } else if (action instanceof MoveMouseMacroAction) { return TabName.Move; - } else if (action.macroActionType === macroActionType.ScrollMouseMacroAction) { + } else if (action instanceof ScrollMouseMacroAction) { return TabName.Scroll; } return TabName.Move; } - getMacroActionType(tab: TabName): string { - if (tab === TabName.Click || tab === TabName.Hold || tab === TabName.Release) { - return macroActionType.MouseButtonMacroAction; - } else if (tab === TabName.Move) { - return macroActionType.MoveMouseMacroAction; - } else if (tab === TabName.Scroll) { - return macroActionType.ScrollMouseMacroAction; - } - } - } diff --git a/shared/src/components/macro/action-editor/tab/text/macro-text.component.ts b/shared/src/components/macro/action-editor/tab/text/macro-text.component.ts index 43e99c80..e85c0fae 100644 --- a/shared/src/components/macro/action-editor/tab/text/macro-text.component.ts +++ b/shared/src/components/macro/action-editor/tab/text/macro-text.component.ts @@ -1,4 +1,5 @@ import { + OnInit, AfterViewInit, Component, ElementRef, @@ -7,7 +8,7 @@ import { ViewChild } from '@angular/core'; -import { EditableMacroAction } from '../../../../../config-serializer/config-items/macro-action'; +import { TextMacroAction } from '../../../../../config-serializer/config-items/macro-action'; @Component({ selector: 'macro-text-tab', @@ -15,12 +16,18 @@ import { EditableMacroAction } from '../../../../../config-serializer/config-ite styleUrls: ['./macro-text.component.scss'], host: { 'class': 'macro__text' } }) -export class MacroTextTabComponent implements AfterViewInit { - @Input() macroAction: EditableMacroAction; +export class MacroTextTabComponent implements OnInit, AfterViewInit { + @Input() macroAction: TextMacroAction; @ViewChild('macroTextInput') input: ElementRef; constructor(private renderer: Renderer) {} + ngOnInit() { + if (!this.macroAction) { + this.macroAction = new TextMacroAction(); + } + } + ngAfterViewInit() { this.renderer.invokeElementMethod(this.input.nativeElement, 'focus'); } diff --git a/shared/src/components/macro/item/macro-item.component.ts b/shared/src/components/macro/item/macro-item.component.ts index cbf2e465..f2ef212d 100644 --- a/shared/src/components/macro/item/macro-item.component.ts +++ b/shared/src/components/macro/item/macro-item.component.ts @@ -148,7 +148,7 @@ export class MacroItemComponent implements OnInit, OnChanges { if (action.hasModifiers()) { // Press/hold/release modifiers - for (let i = KeyModifiers.leftCtrl; i !== KeyModifiers.rightGui; i <<= 1) { + for (let i = KeyModifiers.leftCtrl; i <= KeyModifiers.rightGui; i <<= 1) { if (action.isModifierActive(i)) { this.title += ' ' + KeyModifiers[i]; } diff --git a/shared/src/config-serializer/config-items/macro-action/editable-macro-action.ts b/shared/src/config-serializer/config-items/macro-action/editable-macro-action.ts deleted file mode 100644 index 84355dce..00000000 --- a/shared/src/config-serializer/config-items/macro-action/editable-macro-action.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { KeyAction, KeystrokeAction, keyActionType } from '../key-action'; -import { KeystrokeType } from '../key-action/keystroke-type'; -import { DelayMacroAction } from './delay-macro-action'; -import { KeyMacroAction } from './key-macro-action'; -import { MacroAction, MacroSubAction, macroActionType } from './macro-action'; -import { MouseButtonMacroAction } from './mouse-button-macro-action'; -import { MoveMouseMacroAction } from './move-mouse-macro-action'; -import { ScrollMouseMacroAction } from './scroll-mouse-macro-action'; -import { TextMacroAction } from './text-macro-action'; - -interface JsObjectEditableMacroAction { - macroActionType: string; - action?: string; - scancode?: number; - type?: string; - modifierMask?: number; - mouseButtonsMask?: number; - x?: number; - y?: number; - delay?: number; - text?: string; -} - -export class EditableMacroAction { - macroActionType: string; - action: MacroSubAction; - // Key macro action properties - type: number; - scancode: number; - modifierMask: number; - // Mouse macro action properties - mouseButtonsMask: number; - moveX: number; - moveY: number; - scrollX: number; - scrollY: number; - // Delay macro action properties - delay: number; - // Text macro action properties - text: string; - - constructor(jsObject?: JsObjectEditableMacroAction) { - if (!jsObject) { - return; - } - - this.macroActionType = jsObject.macroActionType; - - switch (this.macroActionType) { - case macroActionType.KeyMacroAction: - this.action = MacroSubAction[jsObject.action]; - this.type = KeystrokeType[jsObject.type]; - this.scancode = jsObject.scancode; - this.modifierMask = jsObject.modifierMask; - break; - case macroActionType.MouseButtonMacroAction: - this.action = MacroSubAction[jsObject.action]; - this.mouseButtonsMask = jsObject.mouseButtonsMask; - break; - case macroActionType.MoveMouseMacroAction: - this.moveX = jsObject.x; - this.moveY = jsObject.y; - break; - case macroActionType.ScrollMouseMacroAction: - this.scrollX = jsObject.x; - this.scrollY = jsObject.y; - break; - case macroActionType.TextMacroAction: - this.text = jsObject.text; - break; - case macroActionType.DelayMacroAction: - this.delay = jsObject.delay; - break; - default: - break; - } - } - - toJsObject(): any { - return { - macroActionType: this.macroActionType, - action: this.action, - delay: this.delay, - text: this.text, - type: KeystrokeType[this.type], - scancode: this.scancode, - modifierMask: this.modifierMask, - mouseButtonsMask: this.mouseButtonsMask, - mouseMove: { - x: this.moveX, - y: this.moveY - }, - mouseScroll: { - x: this.scrollX, - y: this.scrollY - } - }; - } - - fromKeyAction(keyAction: KeyAction): void { - const data = keyAction.toJsonObject(); - this.scancode = data.scancode; - this.type = KeystrokeType[data.type as string]; - this.modifierMask = data.modifierMask; - } - - toKeystrokeAction(): KeystrokeAction { - const data = this.toJsObject(); - data.keyActionType = keyActionType.KeystrokeAction; - return (new KeystrokeAction().fromJsonObject(data)); - } - - setMouseButtons(buttonStates: boolean[]): void { - let bitmask = 0; - for (let i = 0; i < buttonStates.length; i++) { - bitmask |= Number(buttonStates[i]) << i; - } - this.mouseButtonsMask = bitmask; - } - - getMouseButtons(): boolean[] { - const enabledMouseButtons: boolean[] = []; - for (let bitmask = this.mouseButtonsMask; bitmask; bitmask >>>= 1) { - enabledMouseButtons.push(Boolean(bitmask & 1)); - } - return enabledMouseButtons; - } - - toClass(): MacroAction { - switch (this.macroActionType) { - // Delay action - case macroActionType.DelayMacroAction: - return new DelayMacroAction().fromJsonObject({ - macroActionType: this.macroActionType, - delay: this.delay - }); - // Text action - case macroActionType.TextMacroAction: - return new TextMacroAction().fromJsonObject({ - macroActionType: this.macroActionType, - text: this.text - }); - // Keypress action - case macroActionType.KeyMacroAction: - return new KeyMacroAction().fromJsonObject({ - macroActionType: this.macroActionType, - action: MacroSubAction[this.action], - type: KeystrokeType[this.type], - scancode: this.scancode, - modifierMask: this.modifierMask - }); - // Mouse actions - case macroActionType.MouseButtonMacroAction: - return new MouseButtonMacroAction().fromJsonObject({ - macroActionType: this.macroActionType, - action: MacroSubAction[this.action], - mouseButtonsMask: this.mouseButtonsMask - }); - case macroActionType.MoveMouseMacroAction: - return new MoveMouseMacroAction().fromJsonObject({ - macroActionType: this.macroActionType, - x: this.moveX, - y: this.moveY - }); - case macroActionType.ScrollMouseMacroAction: - return new ScrollMouseMacroAction().fromJsonObject({ - macroActionType: this.macroActionType, - x: this.scrollX, - y: this.scrollY - }); - default: - throw new Error('Macro action type is missing or not implemented.'); - } - } - - isKeyAction(): boolean { - return this.macroActionType === macroActionType.KeyMacroAction; - } - - isMouseButtonAction(): boolean { - return this.macroActionType === macroActionType.MouseButtonMacroAction; - } - - isOnlyHoldAction(): boolean { - return this.action === MacroSubAction.hold; - } - - isOnlyPressAction(): boolean { - return this.action === MacroSubAction.press; - } - - isOnlyReleaseAction(): boolean { - return this.action === MacroSubAction.release; - } - -} diff --git a/shared/src/config-serializer/config-items/macro-action/index.ts b/shared/src/config-serializer/config-items/macro-action/index.ts index 127ec22d..63456b7a 100644 --- a/shared/src/config-serializer/config-items/macro-action/index.ts +++ b/shared/src/config-serializer/config-items/macro-action/index.ts @@ -1,5 +1,4 @@ export * from './delay-macro-action'; -export * from './editable-macro-action'; export * from './key-macro-action'; export * from './macro-action'; export * from './move-mouse-macro-action';