Macro editor (#87)

This commit is contained in:
Mikko Lakomaa
2016-09-13 22:22:11 +03:00
committed by József Farkas
parent 8a76da8df5
commit fbb4a1cc49
61 changed files with 1638 additions and 429 deletions

View File

@@ -0,0 +1,189 @@
import { KeyAction, KeystrokeAction, keyActionType } from '../key-action';
import { DelayMacroAction } from './DelayMacroAction';
import { KeyMacroAction } from './KeyMacroAction';
import { MacroAction, MacroSubAction, macroActionType } from './MacroAction';
import { MouseButtonMacroAction } from './MouseButtonMacroAction';
import { MoveMouseMacroAction } from './MoveMouseMacroAction';
import { ScrollMouseMacroAction } from './ScrollMouseMacroAction';
import { TextMacroAction } from './TextMacroAction';
interface JsObjectEditableMacroAction {
macroActionType: string;
action?: string;
scancode?: number;
modifierMask?: number;
mouseButtonsMask?: number;
x?: number;
y?: number;
delay?: number;
text?: string;
}
export class EditableMacroAction {
macroActionType: string;
action: MacroSubAction;
// Key macro action properties
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.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,
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 {
let data = keyAction.toJsObject();
this.scancode = data.scancode;
this.modifierMask = data.modifierMask;
}
toKeystrokeAction(): KeystrokeAction {
let data = this.toJsObject();
data.keyActionType = keyActionType.KeystrokeAction;
return <KeystrokeAction>(new KeystrokeAction().fromJsObject(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[] {
let 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().fromJsObject({
macroActionType: this.macroActionType,
delay: this.delay
});
// Text action
case macroActionType.TextMacroAction:
return new TextMacroAction().fromJsObject({
macroActionType: this.macroActionType,
text: this.text
});
// Keypress action
case macroActionType.KeyMacroAction:
return new KeyMacroAction().fromJsObject({
macroActionType: this.macroActionType,
action: MacroSubAction[this.action],
scancode: this.scancode,
modifierMask: this.modifierMask
});
// Mouse actions
case macroActionType.MouseButtonMacroAction:
return new MouseButtonMacroAction().fromJsObject({
macroActionType: this.macroActionType,
action: MacroSubAction[this.action],
mouseButtonsMask: this.mouseButtonsMask
});
case macroActionType.MoveMouseMacroAction:
return new MoveMouseMacroAction().fromJsObject({
macroActionType: this.macroActionType,
x: this.moveX,
y: this.moveY
});
case macroActionType.ScrollMouseMacroAction:
return new ScrollMouseMacroAction().fromJsObject({
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;
}
}

View File

@@ -1,37 +0,0 @@
import {assertUInt8} from '../../assert';
import {UhkBuffer} from '../../UhkBuffer';
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
export class HoldMouseButtonsMacroAction extends MacroAction {
@assertUInt8
mouseButtonsMask: number;
_fromJsObject(jsObject: any): HoldMouseButtonsMacroAction {
this.assertMacroActionType(jsObject);
this.mouseButtonsMask = jsObject.mouseButtonsMask;
return this;
}
_fromBinary(buffer: UhkBuffer): HoldMouseButtonsMacroAction {
this.readAndAssertMacroActionId(buffer);
this.mouseButtonsMask = buffer.readUInt8();
return this;
}
_toJsObject(): any {
return {
macroActionType: macroActionType.HoldMouseButtonsMacroAction,
mouseButtonsMask: this.mouseButtonsMask
};
}
_toBinary(buffer: UhkBuffer) {
buffer.writeUInt8(MacroActionId.HoldMouseButtonsMacroAction);
buffer.writeUInt8(this.mouseButtonsMask);
}
toString(): string {
return `<HoldMouseButtonsMacroAction mouseButtonsMask="${this.mouseButtonsMask}">`;
}
}

View File

@@ -1,16 +1,10 @@
import { assertEnum, assertUInt8 } from '../../assert';
import { UhkBuffer} from '../../UhkBuffer';
import { KeyModifiers } from '../KeyModifiers';
import { MacroAction, MacroActionId, macroActionType } from './MacroAction';
import { MacroAction, MacroActionId, MacroSubAction, macroActionType } from './MacroAction';
const NUM_OF_COMBINATIONS = 3; // Cases: scancode, modifer, both
enum Action {
press = 0,
hold = 1,
release = 2
}
interface JsObjectKeyMacroAction {
macroActionType: string;
action: string;
@@ -20,8 +14,8 @@ interface JsObjectKeyMacroAction {
export class KeyMacroAction extends MacroAction {
@assertEnum(Action)
action: Action;
@assertEnum(MacroSubAction)
action: MacroSubAction;
@assertUInt8
scancode: number;
@@ -31,7 +25,7 @@ export class KeyMacroAction extends MacroAction {
_fromJsObject(jsObject: JsObjectKeyMacroAction): KeyMacroAction {
this.assertMacroActionType(jsObject);
this.action = Action[jsObject.action];
this.action = MacroSubAction[jsObject.action];
this.scancode = jsObject.scancode;
this.modifierMask = jsObject.modifierMask;
return this;
@@ -54,7 +48,7 @@ export class KeyMacroAction extends MacroAction {
_toJsObject(): any {
let jsObject: JsObjectKeyMacroAction = {
macroActionType: macroActionType.KeyMacroAction,
action: Action[this.action]
action: MacroSubAction[this.action]
};
if (this.hasScancode()) {
@@ -104,14 +98,14 @@ export class KeyMacroAction extends MacroAction {
}
isHoldAction(): boolean {
return this.action === Action.hold;
return this.action === MacroSubAction.hold;
}
isPressAction(): boolean {
return this.action === Action.press;
return this.action === MacroSubAction.press;
}
isReleaseAction(): boolean {
return this.action === Action.release;
return this.action === MacroSubAction.release;
}
}

View File

@@ -16,20 +16,29 @@ export enum MacroActionId {
ReleaseKeyMacroAction with scancode and modifiers 8
*/
LastKeyMacroAction = 8,
PressMouseButtonsMacroAction = 9,
HoldMouseButtonsMacroAction = 10,
ReleaseMouseButtonsMacroAction = 11,
MouseButtonMacroAction = 9,
/*
9 - 11 are reserved for MouseButtonMacroAction
PressMouseButtonsMacroAction = 9,
HoldMouseButtonsMacroAction = 10,
ReleaseMouseButtonsMacroAction = 11,
*/
LastMouseButtonMacroAction = 11,
MoveMouseMacroAction = 12,
ScrollMouseMacroAction = 13,
DelayMacroAction = 14,
TextMacroAction = 15
}
export enum MacroSubAction {
press = 0,
hold = 1,
release = 2
}
export let macroActionType = {
KeyMacroAction : 'key',
PressMouseButtonsMacroAction : 'pressMouseButtons',
HoldMouseButtonsMacroAction : 'holdMouseButtons',
ReleaseMouseButtonsMacroAction : 'releaseMouseButtons',
MouseButtonMacroAction : 'mouseButton',
MoveMouseMacroAction : 'moveMouse',
ScrollMouseMacroAction : 'scrollMouse',
DelayMacroAction : 'delay',
@@ -53,8 +62,12 @@ export abstract class MacroAction extends Serializable<MacroAction> {
if (readMacroActionId < MacroActionId.KeyMacroAction || readMacroActionId > MacroActionId.LastKeyMacroAction) {
throw `Invalid ${classname} first byte: ${readMacroActionId}`;
}
}
else if (readMacroActionId !== macroActionId) {
} else if (macroActionId === MacroActionId.MouseButtonMacroAction) {
if (readMacroActionId < MacroActionId.MouseButtonMacroAction ||
readMacroActionId > MacroActionId.LastMouseButtonMacroAction) {
throw `Invalid ${classname} first byte: ${readMacroActionId}`;
}
} else if (readMacroActionId !== macroActionId) {
throw `Invalid ${classname} first byte: ${readMacroActionId}`;
}
return readMacroActionId;

View File

@@ -1,12 +1,10 @@
import {ClassArray} from '../../ClassArray';
import {UhkBuffer} from '../../UhkBuffer';
import {DelayMacroAction} from './DelayMacroAction';
import {HoldMouseButtonsMacroAction} from './HoldMouseButtonsMacroAction';
import {KeyMacroAction} from './KeyMacroAction';
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
import {MouseButtonMacroAction} from './MouseButtonMacroAction';
import {MoveMouseMacroAction} from './MoveMouseMacroAction';
import {PressMouseButtonsMacroAction} from './PressMouseButtonsMacroAction';
import {ReleaseMouseButtonsMacroAction} from './ReleaseMouseButtonsMacroAction';
import {ScrollMouseMacroAction} from './ScrollMouseMacroAction';
import {TextMacroAction} from './TextMacroAction';
@@ -16,12 +14,8 @@ export class MacroActions extends ClassArray<MacroAction> {
switch (jsObject.macroActionType) {
case macroActionType.KeyMacroAction:
return new KeyMacroAction().fromJsObject(jsObject);
case macroActionType.PressMouseButtonsMacroAction:
return new PressMouseButtonsMacroAction().fromJsObject(jsObject);
case macroActionType.HoldMouseButtonsMacroAction:
return new HoldMouseButtonsMacroAction().fromJsObject(jsObject);
case macroActionType.ReleaseMouseButtonsMacroAction:
return new ReleaseMouseButtonsMacroAction().fromJsObject(jsObject);
case macroActionType.MouseButtonMacroAction:
return new MouseButtonMacroAction().fromJsObject(jsObject);
case macroActionType.MoveMouseMacroAction:
return new MoveMouseMacroAction().fromJsObject(jsObject);
case macroActionType.ScrollMouseMacroAction:
@@ -48,12 +42,8 @@ export class MacroActions extends ClassArray<MacroAction> {
return new KeyMacroAction().fromBinary(buffer);
}
switch (macroActionFirstByte) {
case MacroActionId.PressMouseButtonsMacroAction:
return new PressMouseButtonsMacroAction().fromBinary(buffer);
case MacroActionId.HoldMouseButtonsMacroAction:
return new HoldMouseButtonsMacroAction().fromBinary(buffer);
case MacroActionId.ReleaseMouseButtonsMacroAction:
return new ReleaseMouseButtonsMacroAction().fromBinary(buffer);
case MacroActionId.MouseButtonMacroAction:
return new MouseButtonMacroAction().fromBinary(buffer);
case MacroActionId.MoveMouseMacroAction:
return new MoveMouseMacroAction().fromBinary(buffer);
case MacroActionId.ScrollMouseMacroAction:

View File

@@ -0,0 +1,85 @@
import { assertEnum, assertUInt8 } from '../../assert';
import { UhkBuffer } from '../../UhkBuffer';
import { MacroAction, MacroActionId, MacroSubAction, macroActionType } from './MacroAction';
export enum MouseButtons {
Left = 1 << 0,
Middle = 1 << 1,
Right = 1 << 2
};
interface JsObjectMouseButtonMacroAction {
macroActionType: string;
action: string;
mouseButtonsMask?: number;
}
export class MouseButtonMacroAction extends MacroAction {
@assertEnum(MacroSubAction)
action: MacroSubAction;
@assertUInt8
mouseButtonsMask: number;
_fromJsObject(jsObject: JsObjectMouseButtonMacroAction): MouseButtonMacroAction {
this.assertMacroActionType(jsObject);
this.action = MacroSubAction[jsObject.action];
this.mouseButtonsMask = jsObject.mouseButtonsMask;
return this;
}
_fromBinary(buffer: UhkBuffer): MouseButtonMacroAction {
this.readAndAssertMacroActionId(buffer);
this.mouseButtonsMask = buffer.readUInt8();
return this;
}
_toJsObject(): any {
return {
macroActionType: macroActionType.MouseButtonMacroAction,
action: MacroSubAction[this.action],
mouseButtonsMask: this.mouseButtonsMask
};
}
_toBinary(buffer: UhkBuffer): void {
buffer.writeUInt8(MacroActionId.MouseButtonMacroAction);
buffer.writeUInt8(this.mouseButtonsMask);
}
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[] {
let enabledMouseButtons: boolean[] = [];
for (let bitmask = this.mouseButtonsMask; bitmask; bitmask >>>= 1) {
enabledMouseButtons.push(Boolean(bitmask & 1));
}
return enabledMouseButtons;
}
toString(): string {
return `<MouseButtonMacroAction mouseButtonsMask="${this.mouseButtonsMask}">`;
}
hasButtons(): boolean {
return this.mouseButtonsMask !== 0;
}
isOnlyHoldAction(): boolean {
return this.action === MacroSubAction.hold;
}
isOnlyPressAction(): boolean {
return this.action === MacroSubAction.press;
}
isOnlyReleaseAction(): boolean {
return this.action === MacroSubAction.release;
}
}

View File

@@ -1,37 +0,0 @@
import {assertUInt8} from '../../assert';
import {UhkBuffer} from '../../UhkBuffer';
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
export class PressMouseButtonsMacroAction extends MacroAction {
@assertUInt8
mouseButtonsMask: number;
_fromJsObject(jsObject: any): PressMouseButtonsMacroAction {
this.assertMacroActionType(jsObject);
this.mouseButtonsMask = jsObject.mouseButtonsMask;
return this;
}
_fromBinary(buffer: UhkBuffer): PressMouseButtonsMacroAction {
this.readAndAssertMacroActionId(buffer);
this.mouseButtonsMask = buffer.readUInt8();
return this;
}
_toJsObject(): any {
return {
macroActionType: macroActionType.PressMouseButtonsMacroAction,
mouseButtonsMask: this.mouseButtonsMask
};
}
_toBinary(buffer: UhkBuffer) {
buffer.writeUInt8(MacroActionId.PressMouseButtonsMacroAction);
buffer.writeUInt8(this.mouseButtonsMask);
}
toString(): string {
return `<PressMouseButtonsMacroAction mouseButtonsMask="${this.mouseButtonsMask}">`;
}
}

View File

@@ -1,37 +0,0 @@
import {assertUInt8} from '../../assert';
import {UhkBuffer} from '../../UhkBuffer';
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
export class ReleaseMouseButtonsMacroAction extends MacroAction {
@assertUInt8
mouseButtonsMask: number;
_fromJsObject(jsObject: any): ReleaseMouseButtonsMacroAction {
this.assertMacroActionType(jsObject);
this.mouseButtonsMask = jsObject.mouseButtonsMask;
return this;
}
_fromBinary(buffer: UhkBuffer): ReleaseMouseButtonsMacroAction {
this.readAndAssertMacroActionId(buffer);
this.mouseButtonsMask = buffer.readUInt8();
return this;
}
_toJsObject(): any {
return {
macroActionType: macroActionType.ReleaseMouseButtonsMacroAction,
mouseButtonsMask: this.mouseButtonsMask
};
}
_toBinary(buffer: UhkBuffer) {
buffer.writeUInt8(MacroActionId.ReleaseMouseButtonsMacroAction);
buffer.writeUInt8(this.mouseButtonsMask);
}
toString(): string {
return `<ReleaseMouseButtonsMacroAction mouseButtonsMask="${this.mouseButtonsMask}">`;
}
}

View File

@@ -1,10 +1,9 @@
export * from './DelayMacroAction';
export * from './HoldMouseButtonsMacroAction';
export * from './EditableMacroAction';
export * from './KeyMacroAction';
export * from './MacroAction';
export * from './MacroActions';
export * from './MoveMouseMacroAction';
export * from './PressMouseButtonsMacroAction';
export * from './ReleaseMouseButtonsMacroAction';
export * from './MouseButtonMacroAction';
export * from './ScrollMouseMacroAction';
export * from './TextMacroAction';

View File

@@ -1015,15 +1015,18 @@
"modifierMask": 133
},
{
"macroActionType": "pressMouseButtons",
"macroActionType": "mouseButton",
"action": "press",
"mouseButtonsMask": 9
},
{
"macroActionType": "holdMouseButtons",
"macroActionType": "mouseButton",
"action": "hold",
"mouseButtonsMask": 12
},
{
"macroActionType": "releaseMouseButtons",
"macroActionType": "mouseButton",
"action": "release",
"mouseButtonsMask": 104
},
{
@@ -1058,7 +1061,8 @@
"scancode": 111
},
{
"macroActionType": "releaseMouseButtons",
"macroActionType": "mouseButton",
"action": "release",
"mouseButtonsMask": 104
},
{