Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
123cab5724 | ||
|
|
c16365a0e5 | ||
|
|
a21d278c0c | ||
|
|
0466916be1 | ||
|
|
9a845d8f6a | ||
|
|
9ae1673499 | ||
|
|
2d5a5e7aef | ||
|
|
3e4d439852 | ||
|
|
aba0b09109 | ||
|
|
af608ee17d | ||
|
|
df817e86d6 | ||
|
|
a7d3b62512 | ||
|
|
b41f14192a | ||
|
|
475ec71983 | ||
|
|
b5cff2fa93 | ||
|
|
80e8c014ec | ||
|
|
67d42f666c | ||
|
|
fa32f95438 | ||
|
|
06878dd56a |
19
CHANGELOG.md
@@ -6,6 +6,25 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1
|
||||
|
||||
Every Agent version includes the most recent firmware version. See the [firmware changelog](https://github.com/UltimateHackingKeyboard/firmware/blob/master/CHANGELOG.md).
|
||||
|
||||
## [1.2.9] - 2018-09-13
|
||||
|
||||
Firmware: 8.2.5 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.4.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
||||
|
||||
- Display OS-specific modifiers.
|
||||
- Display secondary roles.
|
||||
- Don't trigger "Remap on all layers" after leaving Agent with Alt+Tab.
|
||||
|
||||
## [1.2.8] - 2018-08-26
|
||||
|
||||
Firmware: 8.**2.5** [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.2.5)] | Device Protocol: 4.4.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
||||
|
||||
- Uncheck the "Remap on all keymaps" and "Remap on all layers" checkboxes of the key action popover by default.
|
||||
- Bind left and right Shift on the Mouse layer of all keymaps in the default configuration.
|
||||
- Make ng2-select2 widgets faster.
|
||||
- Add note to the LED brightness page saying that current UHK versions are not backlit.
|
||||
- Fix the padding of the secondary role tooltip.
|
||||
- Remove the redundant scrollbar from the LED brightness page.
|
||||
|
||||
## [1.2.7] - 2018-07-26
|
||||
|
||||
Firmware: 8.4.0 [[release](https://github.com/UltimateHackingKeyboard/firmware/releases/tag/v8.4.0)] | Device Protocol: 4.4.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
||||
|
||||
9554
package-lock.json
generated
27
package.json
@@ -3,8 +3,8 @@
|
||||
"private": true,
|
||||
"author": "Ultimate Gadget Laboratories",
|
||||
"main": "electron/dist/electron-main.js",
|
||||
"version": "1.2.7",
|
||||
"firmwareVersion": "8.4.0",
|
||||
"version": "1.2.9",
|
||||
"firmwareVersion": "8.2.5",
|
||||
"deviceProtocolVersion": "4.4.0",
|
||||
"userConfigVersion": "4.0.1",
|
||||
"hardwareConfigVersion": "1.0.0",
|
||||
@@ -22,7 +22,7 @@
|
||||
"@types/electron-devtools-installer": "2.0.2",
|
||||
"@types/electron-settings": "3.0.0",
|
||||
"@types/fs-extra": "5.0.1",
|
||||
"@types/jasmine": "2.6.0",
|
||||
"@types/jasmine": "2.8.8",
|
||||
"@types/jquery": "3.3.1",
|
||||
"@types/jsonfile": "4.0.1",
|
||||
"@types/lodash-es": "4.17.0",
|
||||
@@ -40,35 +40,39 @@
|
||||
"decompress": "4.2.0",
|
||||
"decompress-tarbz2": "4.1.1",
|
||||
"devtron": "1.4.0",
|
||||
"electron": "1.8.4",
|
||||
"electron": "1.8.7",
|
||||
"electron-builder": "20.8.1",
|
||||
"electron-debug": "1.5.0",
|
||||
"electron-devtools-installer": "2.2.3",
|
||||
"electron-log": "2.2.16",
|
||||
"electron-rebuild": "1.8.1",
|
||||
"electron-rebuild": "1.8.2",
|
||||
"electron-settings": "3.1.4",
|
||||
"electron-updater": "2.21.4",
|
||||
"exports-loader": "0.6.3",
|
||||
"file-loader": "0.10.0",
|
||||
"fs-extra": "5.0.0",
|
||||
"gh-pages": "1.1.0",
|
||||
"jasmine": "2.8.0",
|
||||
"jasmine-core": "2.8.0",
|
||||
"jasmine-node": "2.0.1",
|
||||
"jasmine-ts": "0.2.1",
|
||||
"jsonfile": "4.0.0",
|
||||
"lerna": "2.9.0",
|
||||
"lerna": "3.1.4",
|
||||
"lodash-es": "4.17.4",
|
||||
"mkdirp": "0.5.1",
|
||||
"node-hid": "0.5.7",
|
||||
"npm-run-all": "4.0.2",
|
||||
"pre-commit": "1.2.2",
|
||||
"request": "2.83.0",
|
||||
"request": "2.88.0",
|
||||
"rimraf": "2.6.1",
|
||||
"standard-version": "4.2.0",
|
||||
"stylelint": "7.13.0",
|
||||
"svg-sprite": "1.3.7",
|
||||
"stylelint": "9.5.0",
|
||||
"svg-sprite": "1.4.0",
|
||||
"ts-loader": "2.3.1",
|
||||
"ts-node": "3.0.4",
|
||||
"ts-node": "7.0.1",
|
||||
"tslint": "5.9.1",
|
||||
"typescript": "2.6.2",
|
||||
"webpack": "3.10.0"
|
||||
"webpack": "3.12.0"
|
||||
},
|
||||
"pre-commit": [
|
||||
"precommit-msg"
|
||||
@@ -88,6 +92,7 @@
|
||||
"lint:ts:test-serializer": "tslint --project ./packages/test-serializer/tsconfig.json",
|
||||
"lint:ts:uhk-usb": "tslint --project ./packages/uhk-usb/tsconfig.json",
|
||||
"lint:style": "stylelint \"packages/uhk-agent/src/**/*.scss\" \"packages/uhk-web/src/**/*.scss\" --syntax scss",
|
||||
"e2e": "lerna run e2e --scope uhk-web",
|
||||
"prebuild": "check-node-version --package",
|
||||
"build": "run-s build:common build:usb build:web build:electron",
|
||||
"build:web": "lerna exec --scope uhk-web npm run build",
|
||||
|
||||
146
packages/test-serializer/package-lock.json
generated
@@ -201,11 +201,11 @@
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"gaze": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz",
|
||||
"integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
|
||||
"integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
|
||||
"requires": {
|
||||
"globule": "0.1.0"
|
||||
"globule": "1.2.1"
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
@@ -219,41 +219,37 @@
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
|
||||
},
|
||||
"glob": {
|
||||
"version": "3.1.21",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
|
||||
"integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "1.2.3",
|
||||
"inherits": "1.0.2",
|
||||
"minimatch": "0.2.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
|
||||
"integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js="
|
||||
}
|
||||
"fs.realpath": "1.0.0",
|
||||
"inflight": "1.0.6",
|
||||
"inherits": "2.0.3",
|
||||
"minimatch": "3.0.4",
|
||||
"once": "1.4.0",
|
||||
"path-is-absolute": "1.0.1"
|
||||
}
|
||||
},
|
||||
"globule": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz",
|
||||
"integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
|
||||
"integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
|
||||
"requires": {
|
||||
"glob": "3.1.21",
|
||||
"lodash": "1.0.2",
|
||||
"minimatch": "0.2.14"
|
||||
"glob": "7.1.2",
|
||||
"lodash": "4.17.10",
|
||||
"minimatch": "3.0.4"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
|
||||
"integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q="
|
||||
},
|
||||
"growl": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz",
|
||||
"integrity": "sha1-3i1mE20ALhErpw8/EMMc98NQsto="
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA=="
|
||||
},
|
||||
"grunt-exec": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-0.4.7.tgz",
|
||||
"integrity": "sha1-QAUf+k6wyWV+BTuV6I1ENSocLCU="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "2.0.0",
|
||||
@@ -362,31 +358,34 @@
|
||||
"integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4="
|
||||
},
|
||||
"jasmine-growl-reporter": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-0.2.1.tgz",
|
||||
"integrity": "sha1-1fCje5L2qD/VxkgrgJSVyQqLVf4=",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-1.0.1.tgz",
|
||||
"integrity": "sha512-dh7VjP3l0OLxL9+sw5vK6RrdH4gdHCNkTnUd9orViHDPr7Fe8LsXY+IObWauS2hX5khMFtjKRZCfTcDHKAjm/A==",
|
||||
"requires": {
|
||||
"growl": "1.7.0"
|
||||
"growl": "1.10.5"
|
||||
}
|
||||
},
|
||||
"jasmine-node": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-node/-/jasmine-node-2.0.0.tgz",
|
||||
"integrity": "sha1-gXUacjJfVJdJCxQYGlUIfxsDcf8=",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-node/-/jasmine-node-2.0.1.tgz",
|
||||
"integrity": "sha512-1S5Z4Mof5yxwqLIApzyo2pV5WN2kRpTSgICvEo3+rJmKve9P94kolzC9eS0u5cyiT+gxBY2mwOQdxLbkhwKzoA==",
|
||||
"requires": {
|
||||
"coffee-script": "1.7.1",
|
||||
"gaze": "0.5.2",
|
||||
"jasmine-growl-reporter": "0.2.1",
|
||||
"minimist": "0.0.8",
|
||||
"gaze": "1.1.3",
|
||||
"grunt-exec": "0.4.7",
|
||||
"jasmine-growl-reporter": "1.0.1",
|
||||
"jasmine-reporters": "git://github.com/larrymyers/jasmine-reporters.git#2c7242dc11c15c2f156169bc704798568b8cb50d",
|
||||
"minimist": "0.0.10",
|
||||
"mkdirp": "0.3.5",
|
||||
"underscore": "1.6.0",
|
||||
"walkdir": "0.0.12"
|
||||
"walkdir": "0.0.12",
|
||||
"xml2js": "0.4.19"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
||||
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.3.5",
|
||||
@@ -395,6 +394,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"jasmine-reporters": {
|
||||
"version": "git://github.com/larrymyers/jasmine-reporters.git#2c7242dc11c15c2f156169bc704798568b8cb50d",
|
||||
"requires": {
|
||||
"mkdirp": "0.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"mkdirp": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
|
||||
"integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc="
|
||||
}
|
||||
}
|
||||
},
|
||||
"jasmine-ts": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-ts/-/jasmine-ts-0.2.1.tgz",
|
||||
@@ -442,14 +454,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz",
|
||||
"integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "2.7.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
|
||||
"integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI="
|
||||
"version": "4.17.10",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.0",
|
||||
@@ -470,12 +477,11 @@
|
||||
"integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "0.2.14",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
|
||||
"integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"lru-cache": "2.7.3",
|
||||
"sigmund": "1.0.1"
|
||||
"brace-expansion": "1.1.8"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
@@ -633,6 +639,11 @@
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
|
||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
|
||||
@@ -656,11 +667,6 @@
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
|
||||
},
|
||||
"sigmund": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
|
||||
"integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA="
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
@@ -854,6 +860,20 @@
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.19",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
|
||||
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
|
||||
"requires": {
|
||||
"sax": "1.2.4",
|
||||
"xmlbuilder": "9.0.7"
|
||||
}
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "9.0.7",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
|
||||
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
|
||||
@@ -14,16 +14,9 @@
|
||||
"npm": ">=5.1.0 <6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"uhk-common": "1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jasmine": "2.6.0",
|
||||
"@types/node": "8.0.30",
|
||||
"jasmine": "2.8.0",
|
||||
"jasmine-core": "2.8.0",
|
||||
"jasmine-node": "2.0.0",
|
||||
"jasmine-ts": "0.2.1",
|
||||
"ts-node": "3.3.0",
|
||||
"uhk-common": "1.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jasmine-ts --config=jasmine.json"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"typeRoots": [
|
||||
"./node_modules/@types"
|
||||
]
|
||||
"experimentalDecorators": true
|
||||
}
|
||||
}
|
||||
|
||||
11
packages/uhk-agent/package-lock.json
generated
@@ -1,11 +1,14 @@
|
||||
{
|
||||
"requires": true,
|
||||
"name": "uhk-agent",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/decompress": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/decompress/-/decompress-4.2.0.tgz",
|
||||
"integrity": "sha512-f7bLkRy09Z+1kid9ylcWMRlJrEWe4ceqtoGvlFQ/hnxL7WIr+AEy5Bv8SCIRDm8FLqTv4VF+hTUCpSd7rHgtkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.33"
|
||||
}
|
||||
@@ -13,12 +16,14 @@
|
||||
"@types/node": {
|
||||
"version": "8.0.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.33.tgz",
|
||||
"integrity": "sha512-vmCdO8Bm1ExT+FWfC9sd9r4jwqM7o97gGy2WBshkkXbf/2nLAJQUrZfIhw27yVOtLUev6kSZc4cav/46KbDd8A=="
|
||||
"integrity": "sha512-vmCdO8Bm1ExT+FWfC9sd9r4jwqM7o97gGy2WBshkkXbf/2nLAJQUrZfIhw27yVOtLUev6kSZc4cav/46KbDd8A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz",
|
||||
"integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0="
|
||||
"integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
|
||||
@@ -19,16 +19,6 @@
|
||||
"coverage": "nyc jasmine-ts --config=jasmine.json"
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"devDependencies": {
|
||||
"@types/jasmine": "2.6.0",
|
||||
"@types/node": "8.0.30",
|
||||
"jasmine": "2.8.0",
|
||||
"jasmine-core": "2.8.0",
|
||||
"jasmine-node": "2.0.0",
|
||||
"jasmine-ts": "0.2.1",
|
||||
"nyc": "11.2.1",
|
||||
"ts-node": "3.3.0"
|
||||
},
|
||||
"nyc": {
|
||||
"extension": [
|
||||
".ts"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"sourceMap": true,
|
||||
@@ -9,9 +10,6 @@
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es5",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2015.iterable",
|
||||
"dom",
|
||||
|
||||
7
packages/uhk-usb/package-lock.json
generated
@@ -1,11 +1,14 @@
|
||||
{
|
||||
"requires": true,
|
||||
"name": "uhk-usb",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "8.0.28",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.28.tgz",
|
||||
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ=="
|
||||
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
|
||||
1
packages/uhk-web/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
out-tsc/
|
||||
@@ -7,8 +7,8 @@ describe('web App', () => {
|
||||
page = new WebPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
it('should display default device name', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('Welcome to app!');
|
||||
expect(page.getDeviceName()).toEqual('My UHK');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,8 @@ export class WebPage {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
getDeviceName() {
|
||||
return element(by.css('body > main-app > side-menu > ul > li:nth-child(1) > div > auto-grow-input > input'))
|
||||
.getAttribute('value');
|
||||
}
|
||||
}
|
||||
|
||||
8070
packages/uhk-web/package-lock.json
generated
@@ -36,8 +36,8 @@
|
||||
"@types/electron-devtools-installer": "2.0.2",
|
||||
"@types/electron-settings": "3.0.0",
|
||||
"@types/file-saver": "0.0.1",
|
||||
"@types/jasmine": "2.5.53",
|
||||
"@types/jasminewd2": "2.0.2",
|
||||
"@types/jasmine": "2.8.8",
|
||||
"@types/jasminewd2": "2.0.3",
|
||||
"@types/jquery": "3.2.9",
|
||||
"@types/usb": "1.1.3",
|
||||
"angular-confirmation-popover": "3.2.0",
|
||||
@@ -50,23 +50,23 @@
|
||||
"dragula": "3.7.2",
|
||||
"font-awesome": "4.7.0",
|
||||
"html-webpack-plugin": "^2.29.0",
|
||||
"jasmine-core": "2.6.2",
|
||||
"jasmine-spec-reporter": "4.1.0",
|
||||
"jasmine-core": "3.2.1",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"jquery": "3.2.1",
|
||||
"jsonfile": "3.0.1",
|
||||
"karma": "1.7.0",
|
||||
"karma-chrome-launcher": "2.1.1",
|
||||
"karma-coverage-istanbul-reporter": "1.2.1",
|
||||
"karma-jasmine": "1.1.0",
|
||||
"karma-jasmine-html-reporter": "0.2.2",
|
||||
"karma": "3.0.0",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "2.0.1",
|
||||
"karma-jasmine": "1.1.2",
|
||||
"karma-jasmine-html-reporter": "1.3.1",
|
||||
"ng2-dragula": "1.5.0",
|
||||
"ng2-nouislider": "^1.7.7",
|
||||
"ngx-clipboard": "10.0.0",
|
||||
"@ert78gb/ngx-select-ex": "3.7.0",
|
||||
"@ert78gb/ngx-select-ex": "3.7.2",
|
||||
"ngrx-store-freeze": "0.1.9",
|
||||
"nouislider": "^11.1.0",
|
||||
"postcss-url": "^7.1.2",
|
||||
"protractor": "5.1.2",
|
||||
"protractor": "5.4.0",
|
||||
"reselect": "3.0.1",
|
||||
"rxjs": "5.5.8",
|
||||
"typescript": "2.6.2",
|
||||
@@ -78,6 +78,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"classlist.js": "1.1.20150312",
|
||||
"file-saver": "1.3.3"
|
||||
"file-saver": "1.3.3",
|
||||
"spacing-bootstrap-3": "^1.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ exports.config = {
|
||||
'browserName': 'chrome'
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
baseUrl: 'http://localhost:8080/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<div class="row led-setting">
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<slider-wrapper
|
||||
label="Key backlight brightness"
|
||||
label="Key backlight brightness <span class='text-muted pl-1'>Please note that current UHK versions are not backlit.</span>"
|
||||
[min]="0"
|
||||
[max]="255"
|
||||
[step]="1"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
:host {
|
||||
overflow-y: auto;
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Keymap } from 'uhk-common';
|
||||
|
||||
@@ -14,6 +14,7 @@ import { KeymapActions } from '../../../store/actions';
|
||||
selector: 'keymap-add',
|
||||
templateUrl: './keymap-add.component.html',
|
||||
styleUrls: ['./keymap-add.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
host: {
|
||||
'class': 'container-fluid'
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, HostListener } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Keymap } from 'uhk-common';
|
||||
@@ -24,6 +24,7 @@ import { ChangeKeymapDescription } from '../../../models/ChangeKeymapDescription
|
||||
selector: 'keymap-edit',
|
||||
templateUrl: './keymap-edit.component.html',
|
||||
styleUrls: ['./keymap-edit.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
host: {
|
||||
'class': 'container-fluid'
|
||||
}
|
||||
|
||||
@@ -43,4 +43,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div [ngSwitch]="activeTab">
|
||||
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content"
|
||||
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content pr-10"
|
||||
[defaultKeyAction]="defaultKeyAction"
|
||||
[secondaryRoleEnabled]="true"
|
||||
(validAction)="keyActionValid=$event"
|
||||
@@ -81,14 +81,14 @@
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
name="remapOnAllKeymap"
|
||||
[(ngModel)]="remapOnAllKeymap"> Remap on all keymaps
|
||||
[(ngModel)]="remapInfo.remapOnAllKeymap"> Remap on all keymaps
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
name="remapOnAllLayer"
|
||||
[(ngModel)]="remapOnAllLayer"> Remap on all layers
|
||||
[(ngModel)]="remapInfo.remapOnAllLayer"> Remap on all layers
|
||||
</label>
|
||||
</div>
|
||||
<div class="d-inline-block">
|
||||
|
||||
@@ -99,6 +99,10 @@
|
||||
padding: 10px 24px;
|
||||
}
|
||||
|
||||
.pr-10 {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.popover-overlay {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
@@ -32,6 +33,7 @@ import { Tab } from './tab';
|
||||
import { AppState } from '../../store';
|
||||
import { getKeymaps } from '../../store/reducers/user-configuration';
|
||||
import { KeyActionRemap } from '../../models/key-action-remap';
|
||||
import { RemapInfo } from '../../models/remap-info';
|
||||
|
||||
enum TabName {
|
||||
Keypress,
|
||||
@@ -46,6 +48,7 @@ enum TabName {
|
||||
selector: 'popover',
|
||||
templateUrl: './popover.component.html',
|
||||
styleUrls: ['./popover.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
animations: [
|
||||
trigger('popover', [
|
||||
state('closed', style({
|
||||
@@ -84,8 +87,7 @@ export class PopoverComponent implements OnChanges {
|
||||
@Input() wrapPosition: any;
|
||||
@Input() visible: boolean;
|
||||
@Input() allowLayerDoubleTap: boolean;
|
||||
@Input() remapOnAllKeymap: boolean;
|
||||
@Input() remapOnAllLayer: boolean;
|
||||
@Input() remapInfo: RemapInfo;
|
||||
|
||||
@Output() cancel = new EventEmitter<any>();
|
||||
@Output() remap = new EventEmitter<KeyActionRemap>();
|
||||
@@ -160,8 +162,8 @@ export class PopoverComponent implements OnChanges {
|
||||
if (this.keyActionValid) {
|
||||
try {
|
||||
this.remap.emit({
|
||||
remapOnAllKeymap: this.remapOnAllKeymap,
|
||||
remapOnAllLayer: this.remapOnAllLayer,
|
||||
remapOnAllKeymap: this.remapInfo.remapOnAllKeymap,
|
||||
remapOnAllLayer: this.remapInfo.remapOnAllLayer,
|
||||
action: this.selectedTab.toKeyAction()
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
@@ -36,20 +36,20 @@
|
||||
<div class="btn-toolbar modifiers">
|
||||
<div class="btn-group btn-group-sm modifiers__left">
|
||||
<button type="button" class="btn btn-default"
|
||||
*ngFor="let modifier of leftModifiers; let index = index"
|
||||
[class.btn-primary]="leftModifierSelects[index]"
|
||||
(click)="toggleModifier(false, index)"
|
||||
*ngFor="let modifier of leftModifiers; trackBy:modifiersTrackBy"
|
||||
[class.btn-primary]="modifier.checked"
|
||||
(click)="toggleModifier(modifier)"
|
||||
>
|
||||
{{modifier}}
|
||||
{{ modifier.text }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm modifiers__right">
|
||||
<button type="button" class="btn btn-default"
|
||||
*ngFor="let modifier of rightModifiers; let index = index"
|
||||
[class.btn-primary]="rightModifierSelects[index]"
|
||||
(click)="toggleModifier(true, index)"
|
||||
*ngFor="let modifier of rightModifiers; trackBy:modifiersTrackBy"
|
||||
[class.btn-primary]="modifier.checked"
|
||||
(click)="toggleModifier(modifier)"
|
||||
>
|
||||
{{modifier}}
|
||||
{{ modifier.text }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -88,7 +88,7 @@
|
||||
<li>Tap this key to trigger Escape. <i>(Primary role)</i></li>
|
||||
<li>Hold this key and press another key to activate the relevant key of the Mouse layer. <i>(Secondary role)</i></li>
|
||||
</ul>
|
||||
<p class='text-left pt-3'>The secondary role can be any layer or modifier.</p>"
|
||||
<p class='text-left'>The secondary role can be any layer or modifier.</p>"
|
||||
data-placement="bottom"></icon>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import { KeyAction, KeystrokeAction, KeystrokeType, SCANCODES, SECONDARY_ROLES }
|
||||
import { Tab } from '../tab';
|
||||
import { MapperService } from '../../../../services/mapper.service';
|
||||
import { SelectOptionData } from '../../../../models/select-option-data';
|
||||
import { KeyModifierModel } from '../../../../models/key-modifier-model';
|
||||
import { mapLeftRigthModifierToKeyActionModifier } from '../../../../util';
|
||||
|
||||
@Component({
|
||||
selector: 'keypress-tab',
|
||||
@@ -15,11 +17,8 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
@Input() defaultKeyAction: KeyAction;
|
||||
@Input() secondaryRoleEnabled: boolean;
|
||||
|
||||
leftModifiers: string[];
|
||||
rightModifiers: string[];
|
||||
|
||||
leftModifierSelects: boolean[];
|
||||
rightModifierSelects: boolean[];
|
||||
leftModifiers: KeyModifierModel[];
|
||||
rightModifiers: KeyModifierModel[];
|
||||
|
||||
scanCodeGroups: Array<SelectOptionData>;
|
||||
secondaryRoleGroups: Array<SelectOptionData>;
|
||||
@@ -29,16 +28,15 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
|
||||
constructor(private mapper: MapperService) {
|
||||
super();
|
||||
this.leftModifiers = ['LShift', 'LCtrl', 'LSuper', 'LAlt'];
|
||||
this.rightModifiers = ['RShift', 'RCtrl', 'RSuper', 'RAlt'];
|
||||
this.leftModifiers = mapper.getLeftKeyModifiers();
|
||||
this.rightModifiers = mapper.getRightKeyModifiers();
|
||||
|
||||
this.scanCodeGroups = [{
|
||||
id: '0',
|
||||
text: 'None'
|
||||
}];
|
||||
this.scanCodeGroups = this.scanCodeGroups.concat(SCANCODES);
|
||||
this.secondaryRoleGroups = SECONDARY_ROLES;
|
||||
this.leftModifierSelects = Array(this.leftModifiers.length).fill(false);
|
||||
this.rightModifierSelects = Array(this.rightModifiers.length).fill(false);
|
||||
this.selectedScancodeOption = this.scanCodeGroups[0];
|
||||
this.selectedSecondaryRoleIndex = -1;
|
||||
}
|
||||
@@ -56,15 +54,15 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
return (keystrokeAction) ? (keystrokeAction.scancode > 0 || keystrokeAction.modifierMask > 0) : false;
|
||||
}
|
||||
|
||||
onKeysCapture(event: { code: number, left: boolean[], right: boolean[] }) {
|
||||
onKeysCapture(event: { code: number, left: KeyModifierModel[], right: KeyModifierModel[] }) {
|
||||
if (event.code) {
|
||||
this.selectedScancodeOption = this.findScancodeOptionByScancode(event.code, KeystrokeType.basic);
|
||||
} else {
|
||||
this.selectedScancodeOption = this.scanCodeGroups[0];
|
||||
}
|
||||
|
||||
this.leftModifierSelects = event.left;
|
||||
this.rightModifierSelects = event.right;
|
||||
this.leftModifiers = event.left;
|
||||
this.rightModifiers = event.right;
|
||||
this.validAction.emit(this.keyActionValid());
|
||||
}
|
||||
|
||||
@@ -76,16 +74,12 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
// Restore selectedScancodeOption
|
||||
this.selectedScancodeOption = this.findScancodeOptionByScancode(keystrokeAction.scancode || 0, keystrokeAction.type);
|
||||
|
||||
const leftModifiersLength: number = this.leftModifiers.length;
|
||||
|
||||
// Restore modifiers
|
||||
for (let i = 0; i < leftModifiersLength; ++i) {
|
||||
this.leftModifierSelects[this.mapper.modifierMapper(i)] = ((keystrokeAction.modifierMask >> i) & 1) === 1;
|
||||
for (const modifier of this.leftModifiers) {
|
||||
modifier.checked = (keystrokeAction.modifierMask & modifier.value) > 0;
|
||||
}
|
||||
|
||||
for (let i = leftModifiersLength; i < leftModifiersLength + this.rightModifierSelects.length; ++i) {
|
||||
const index: number = this.mapper.modifierMapper(i) - leftModifiersLength;
|
||||
this.rightModifierSelects[index] = ((keystrokeAction.modifierMask >> i) & 1) === 1;
|
||||
for (const modifier of this.rightModifiers) {
|
||||
modifier.checked = (keystrokeAction.modifierMask & modifier.value) > 0;
|
||||
}
|
||||
|
||||
// Restore secondaryRoleAction
|
||||
@@ -107,11 +101,7 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
} else {
|
||||
keystrokeAction.type = KeystrokeType[scTypePair[1]];
|
||||
}
|
||||
keystrokeAction.modifierMask = 0;
|
||||
const modifiers = this.leftModifierSelects.concat(this.rightModifierSelects).map(x => x ? 1 : 0);
|
||||
for (let i = 0; i < modifiers.length; ++i) {
|
||||
keystrokeAction.modifierMask |= modifiers[i] << this.mapper.modifierMapper(i);
|
||||
}
|
||||
keystrokeAction.modifierMask = mapLeftRigthModifierToKeyActionModifier(this.leftModifiers, this.rightModifiers);
|
||||
|
||||
keystrokeAction.secondaryRoleAction = this.selectedSecondaryRoleIndex === -1
|
||||
? undefined
|
||||
@@ -122,9 +112,8 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
toggleModifier(right: boolean, index: number) {
|
||||
const modifierSelects: boolean[] = right ? this.rightModifierSelects : this.leftModifierSelects;
|
||||
modifierSelects[index] = !modifierSelects[index];
|
||||
toggleModifier(modifier: KeyModifierModel): void {
|
||||
modifier.checked = !modifier.checked;
|
||||
|
||||
this.validAction.emit(this.keyActionValid());
|
||||
}
|
||||
@@ -139,6 +128,10 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
this.validAction.emit(this.keyActionValid());
|
||||
}
|
||||
|
||||
modifiersTrackBy(index: number, modifier: KeyModifierModel): string {
|
||||
return `${modifier.value}${modifier.checked}`;
|
||||
}
|
||||
|
||||
private findScancodeOptionBy(predicate: (option: SelectOptionData) => boolean): SelectOptionData {
|
||||
let selectedOption: SelectOptionData;
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Component, EventEmitter, HostListener, Output, Input } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
|
||||
import { CaptureService } from '../../../../services/capture.service';
|
||||
import { KeyModifierModel } from '../../../../models/key-modifier-model';
|
||||
|
||||
@Component({
|
||||
selector: 'capture-keystroke-button',
|
||||
templateUrl: './capture-keystroke-button.component.html',
|
||||
styleUrls: ['./capture-keystroke-button.component.scss']
|
||||
styleUrls: ['./capture-keystroke-button.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class CaptureKeystrokeButtonComponent {
|
||||
@Input() isLink = false;
|
||||
@@ -67,8 +69,8 @@ export class CaptureKeystrokeButtonComponent {
|
||||
|
||||
private saveScanCode(code?: number) {
|
||||
this.record = false;
|
||||
const left: boolean[] = this.captureService.getModifiers(true);
|
||||
const right: boolean[] = this.captureService.getModifiers(false);
|
||||
const left: KeyModifierModel[] = this.captureService.getModifiers(true);
|
||||
const right: KeyModifierModel[] = this.captureService.getModifiers(false);
|
||||
|
||||
this.capture.emit({
|
||||
code,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'icon',
|
||||
templateUrl: './icon.component.html',
|
||||
styleUrls: ['./icon.component.scss']
|
||||
styleUrls: ['./icon.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class IconComponent implements OnInit {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<label *ngIf="label">
|
||||
<span>{{label}}</span>
|
||||
<span [innerHtml]="label"></span>
|
||||
<icon name="question-circle"
|
||||
data-toggle="tooltip"
|
||||
[title]="tooltip"
|
||||
|
||||
1
packages/uhk-web/src/app/components/svg/constants.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const SECONDARY_ROLE_BOTTOM_MARGIN = 1;
|
||||
@@ -11,3 +11,4 @@ export { SvgSingleIconKeyComponent } from './svg-single-icon-key';
|
||||
export { SvgSwitchKeymapKeyComponent } from './svg-switch-keymap-key';
|
||||
export { SvgTextIconKeyComponent } from './svg-text-icon-key';
|
||||
export { SvgTwoLineTextKeyComponent } from './svg-two-line-text-key';
|
||||
export { SvgSecondaryRoleComponent } from './svg-secondary-role';
|
||||
|
||||
@@ -10,4 +10,11 @@
|
||||
[attr.text-anchor]="'middle'"
|
||||
[attr.font-size]="11">
|
||||
<tspan [attr.x]="spanX">{{ text }}</tspan>
|
||||
</svg:text>
|
||||
</svg:text>
|
||||
<svg:g svg-secondary-role
|
||||
*ngIf="secondaryText"
|
||||
[height]="20"
|
||||
[width]="width"
|
||||
[y]="secondaryTextY"
|
||||
[text]="secondaryText">
|
||||
</svg:g>
|
||||
|
||||
|
Before Width: | Height: | Size: 331 B After Width: | Height: | Size: 499 B |
@@ -1,15 +1,19 @@
|
||||
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
|
||||
|
||||
import { isRectangleAsSecondaryRoleKey } from '../util';
|
||||
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
|
||||
|
||||
@Component({
|
||||
selector: 'g[svg-icon-text-key]',
|
||||
templateUrl: './svg-icon-text-key.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SvgIconTextKeyComponent implements OnInit {
|
||||
export class SvgIconTextKeyComponent implements OnChanges {
|
||||
@Input() width: number;
|
||||
@Input() height: number;
|
||||
@Input() icon: string;
|
||||
@Input() text: string;
|
||||
@Input() secondaryText: string;
|
||||
|
||||
useWidth: number;
|
||||
useHeight: number;
|
||||
@@ -17,16 +21,33 @@ export class SvgIconTextKeyComponent implements OnInit {
|
||||
useY: number;
|
||||
textY: number;
|
||||
spanX: number;
|
||||
secondaryTextY: number;
|
||||
secondaryHeight: number;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.calculatePositions();
|
||||
}
|
||||
|
||||
private calculatePositions(): void {
|
||||
let textYModifier = 0;
|
||||
let secondaryYModifier = 0;
|
||||
|
||||
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
|
||||
textYModifier = this.height / 5;
|
||||
secondaryYModifier = 5;
|
||||
}
|
||||
|
||||
this.useWidth = this.width / 3;
|
||||
this.useHeight = this.height / 3;
|
||||
this.useX = (this.width > 2 * this.height) ? 0 : this.width / 3;
|
||||
this.useY = (this.width > 2 * this.height) ? this.height / 3 : this.height / 10;
|
||||
this.textY = (this.width > 2 * this.height) ? this.height / 2 : this.height * 0.6;
|
||||
this.spanX = (this.width > 2 * this.height) ? this.width * 0.6 : this.width / 2;
|
||||
|
||||
this.secondaryHeight = this.height / 4;
|
||||
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,34 +25,40 @@
|
||||
<svg:g svg-keystroke-key *ngSwitchCase="enumLabelTypes.KeystrokeKey"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
[keystrokeAction]="labelSource">
|
||||
[keystrokeAction]="labelSource"
|
||||
[secondaryText]="secondaryText">
|
||||
</svg:g>
|
||||
<svg:g svg-one-line-text-key *ngSwitchCase="enumLabelTypes.OneLineText"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
[text]="labelSource">
|
||||
[text]="labelSource"
|
||||
[secondaryText]="secondaryText">
|
||||
</svg:g>
|
||||
<svg:g svg-two-line-text-key *ngSwitchCase="enumLabelTypes.TwoLineText"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
[texts]="labelSource">
|
||||
[texts]="labelSource"
|
||||
[secondaryText]="secondaryText">
|
||||
</svg:g>
|
||||
<svg:g svg-text-icon-key *ngSwitchCase="enumLabelTypes.TextIcon"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
[text]="labelSource.text"
|
||||
[icon]="labelSource.icon">
|
||||
[icon]="labelSource.icon"
|
||||
[secondaryText]="secondaryText">
|
||||
</svg:g>
|
||||
<svg:g svg-icon-text-key *ngSwitchCase="enumLabelTypes.IconText"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
[icon]="labelSource.icon"
|
||||
[text]="labelSource.text">
|
||||
[text]="labelSource.text"
|
||||
[secondaryText]="secondaryText">
|
||||
</svg:g>
|
||||
<svg:g svg-single-icon-key *ngSwitchCase="enumLabelTypes.SingleIcon"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
[icon]="labelSource">
|
||||
[icon]="labelSource"
|
||||
[secondaryText]="secondaryText">
|
||||
</svg:g>
|
||||
<svg:g svg-switch-keymap-key *ngSwitchCase="enumLabelTypes.SwitchKeymap"
|
||||
[height]="height"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -27,6 +27,8 @@ import { MapperService } from '../../../../services/mapper.service';
|
||||
import { AppState } from '../../../../store';
|
||||
import { getMacros } from '../../../../store/reducers/user-configuration';
|
||||
import { SvgKeyCaptureEvent, SvgKeyClickEvent } from '../../../../models/svg-key-events';
|
||||
import { OperatingSystem } from '../../../../models/operating-system';
|
||||
import { KeyModifierModel } from '../../../../models/key-modifier-model';
|
||||
|
||||
enum LabelTypes {
|
||||
KeystrokeKey,
|
||||
@@ -94,6 +96,7 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
labelType: LabelTypes;
|
||||
|
||||
labelSource: any;
|
||||
secondaryText: string;
|
||||
macros: Macro[];
|
||||
private subscription: Subscription;
|
||||
private scanCodePressed: boolean;
|
||||
@@ -117,14 +120,16 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.scanCodePressed = false;
|
||||
}
|
||||
|
||||
@HostListener('click')
|
||||
onClick() {
|
||||
@HostListener('click', ['$event'])
|
||||
onClick(e: MouseEvent) {
|
||||
this.reset();
|
||||
this.keyClick.emit({
|
||||
keyTarget: this.element.nativeElement,
|
||||
shiftPressed: this.pressedShiftLocation > -1,
|
||||
altPressed: this.pressedAltLocation > -1
|
||||
shiftPressed: e.shiftKey,
|
||||
altPressed: e.altKey
|
||||
});
|
||||
this.pressedShiftLocation = -1;
|
||||
this.pressedAltLocation = -1;
|
||||
}
|
||||
|
||||
@HostListener('mousedown', ['$event'])
|
||||
@@ -138,14 +143,8 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
} else {
|
||||
this.recording = true;
|
||||
this.recordAnimation = 'active';
|
||||
|
||||
if (this.pressedShiftLocation > -1) {
|
||||
this.shiftPressed = true;
|
||||
}
|
||||
|
||||
if (this.pressedAltLocation > -1) {
|
||||
this.altPressed = true;
|
||||
}
|
||||
this.shiftPressed = e.shiftKey;
|
||||
this.altPressed = e.altKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,8 +245,8 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
private saveScanCode(code = 0) {
|
||||
const left: boolean[] = this.captureService.getModifiers(true);
|
||||
const right: boolean[] = this.captureService.getModifiers(false);
|
||||
const left: KeyModifierModel[] = this.captureService.getModifiers(true);
|
||||
const right: KeyModifierModel[] = this.captureService.getModifiers(false);
|
||||
|
||||
this.capture.emit({
|
||||
captured: {
|
||||
@@ -263,17 +262,18 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
private setLabels(): void {
|
||||
this.labelType = LabelTypes.OneLineText;
|
||||
this.labelSource = undefined;
|
||||
this.secondaryText = undefined;
|
||||
|
||||
if (!this.keyAction) {
|
||||
this.labelSource = undefined;
|
||||
this.labelType = LabelTypes.OneLineText;
|
||||
return;
|
||||
}
|
||||
|
||||
this.labelType = LabelTypes.OneLineText;
|
||||
|
||||
if (this.keyAction instanceof KeystrokeAction) {
|
||||
const keyAction: KeystrokeAction = this.keyAction as KeystrokeAction;
|
||||
let newLabelSource: string[];
|
||||
this.secondaryText = this.mapper.getSecondaryRoleText(keyAction.secondaryRoleAction);
|
||||
|
||||
if (!keyAction.hasActiveModifier() && keyAction.hasScancode()) {
|
||||
const scancode: number = keyAction.scancode;
|
||||
@@ -291,29 +291,32 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
}
|
||||
} else if (keyAction.hasOnlyOneActiveModifier() && !keyAction.hasScancode()) {
|
||||
newLabelSource = [];
|
||||
switch (keyAction.modifierMask) {
|
||||
case KeyModifiers.leftCtrl:
|
||||
case KeyModifiers.rightCtrl:
|
||||
newLabelSource.push('Ctrl');
|
||||
this.labelSource = ['Ctrl'];
|
||||
break;
|
||||
case KeyModifiers.leftShift:
|
||||
case KeyModifiers.rightShift:
|
||||
newLabelSource.push('Shift');
|
||||
this.labelSource = ['Shift'];
|
||||
break;
|
||||
case KeyModifiers.leftAlt:
|
||||
case KeyModifiers.rightAlt:
|
||||
newLabelSource.push('Alt');
|
||||
this.labelSource = [this.mapper.getOsSpecificText('Alt')];
|
||||
break;
|
||||
case KeyModifiers.leftGui:
|
||||
case KeyModifiers.rightGui:
|
||||
newLabelSource.push('Super');
|
||||
if (this.mapper.getOperatingSystem() === OperatingSystem.Windows) {
|
||||
this.labelSource = this.mapper.getIcon('command');
|
||||
this.labelType = LabelTypes.SingleIcon;
|
||||
} else {
|
||||
this.labelSource = [this.mapper.getOsSpecificText('Super')];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
newLabelSource.push('Undefined');
|
||||
this.labelSource = ['Undefined'];
|
||||
break;
|
||||
}
|
||||
this.labelSource = newLabelSource;
|
||||
} else {
|
||||
this.labelType = LabelTypes.KeystrokeKey;
|
||||
this.labelSource = this.keyAction;
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
<svg:g svg-two-line-text-key *ngSwitchCase="'two-line'"
|
||||
[height]="height"
|
||||
[width]="width"
|
||||
[texts]="labelSource">
|
||||
[texts]="labelSource"
|
||||
[secondaryText]="subComponentSecondaryRoleText">
|
||||
</svg:g>
|
||||
</svg>
|
||||
<svg [attr.viewBox]="viewBox" [attr.width]="modifierContainer.width" [attr.height]="modifierContainer.height" [attr.x]="modifierContainer.x"
|
||||
@@ -28,10 +29,19 @@
|
||||
</svg>
|
||||
<svg viewBox="0 0 100 100" [attr.width]="option.width" [attr.height]="option.height" [attr.x]="option.x" [attr.y]="option.y"
|
||||
preserveAspectRatio="none" [class.disabled]="option.disabled">
|
||||
<svg:use [attr.xlink:href]="modifierIconNames.option" />
|
||||
<svg:use *ngIf="modifierIconNames.option" [attr.xlink:href]="modifierIconNames.option" />
|
||||
<svg:text *ngIf="!modifierIconNames.option" [attr.text-anchor]="'middle'" [attr.x]="50" [attr.y]="50">A</svg:text>
|
||||
</svg>
|
||||
<svg viewBox="0 0 100 100" [attr.width]="command.width" [attr.height]="command.height" [attr.x]="command.x" [attr.y]="command.y"
|
||||
preserveAspectRatio="none" [class.disabled]="command.disabled">
|
||||
<svg:use [attr.xlink:href]="modifierIconNames.command" />
|
||||
<svg:use *ngIf="modifierIconNames.command" [attr.xlink:href]="modifierIconNames.command" />
|
||||
<svg:text *ngIf="!modifierIconNames.command" [attr.text-anchor]="'middle'" [attr.x]="50" [attr.y]="50">S</svg:text>
|
||||
</svg>
|
||||
</svg>
|
||||
<svg:g svg-secondary-role
|
||||
*ngIf="thisSecondaryRoleText"
|
||||
[height]="20"
|
||||
[width]="secondaryTextWidth"
|
||||
[y]="secondaryTextY"
|
||||
[text]="thisSecondaryRoleText">
|
||||
</svg:g>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -1,7 +1,9 @@
|
||||
import { Component, Input, OnChanges, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { KeyModifiers, KeystrokeAction } from 'uhk-common';
|
||||
|
||||
import { MapperService } from '../../../../services/mapper.service';
|
||||
import { isRectangleAsSecondaryRoleKey } from '../util';
|
||||
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
|
||||
|
||||
class SvgAttributes {
|
||||
width: number;
|
||||
@@ -25,10 +27,11 @@ class SvgAttributes {
|
||||
styleUrls: ['./svg-keystroke-key.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
|
||||
export class SvgKeystrokeKeyComponent implements OnChanges {
|
||||
@Input() height: number;
|
||||
@Input() width: number;
|
||||
@Input() keystrokeAction: KeystrokeAction;
|
||||
@Input() secondaryText: string;
|
||||
|
||||
viewBox: string;
|
||||
textContainer: SvgAttributes;
|
||||
@@ -46,6 +49,11 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
|
||||
option?: string,
|
||||
command?: string
|
||||
};
|
||||
secondaryTextY: number;
|
||||
secondaryTextWidth: number;
|
||||
secondaryHeight: number;
|
||||
thisSecondaryRoleText: string;
|
||||
subComponentSecondaryRoleText: string;
|
||||
|
||||
constructor(private mapper: MapperService) {
|
||||
this.modifierIconNames = {};
|
||||
@@ -57,15 +65,75 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
|
||||
this.command = new SvgAttributes();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
ngOnChanges() {
|
||||
this.calculatePositions();
|
||||
}
|
||||
|
||||
private calculatePositions(): void {
|
||||
let textYModifier = 0;
|
||||
let secondaryYModifier = 0;
|
||||
this.thisSecondaryRoleText = this.secondaryText;
|
||||
this.subComponentSecondaryRoleText = null;
|
||||
|
||||
const bottomSideMode: boolean = this.width < this.height * 1.8;
|
||||
const isRectangleAsSecondaryRole = isRectangleAsSecondaryRoleKey(this.width, this.height);
|
||||
|
||||
if (this.secondaryText && isRectangleAsSecondaryRole) {
|
||||
textYModifier = this.height / 5;
|
||||
secondaryYModifier = 5;
|
||||
}
|
||||
|
||||
if (this.keystrokeAction.hasScancode()) {
|
||||
const scancode: number = this.keystrokeAction.scancode;
|
||||
this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode, this.keystrokeAction.type);
|
||||
if (this.labelSource) {
|
||||
this.labelType = 'icon';
|
||||
} else {
|
||||
let newLabelSource: string[];
|
||||
newLabelSource = this.mapper.scanCodeToText(scancode, this.keystrokeAction.type);
|
||||
if (newLabelSource) {
|
||||
if (this.secondaryText && newLabelSource.length === 2) {
|
||||
if (isRectangleAsSecondaryRole || bottomSideMode) {
|
||||
this.labelSource = newLabelSource[0];
|
||||
this.labelType = 'one-line';
|
||||
} else {
|
||||
this.labelSource = newLabelSource;
|
||||
this.labelType = 'two-line';
|
||||
this.thisSecondaryRoleText = null;
|
||||
this.subComponentSecondaryRoleText = this.secondaryText;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (newLabelSource.length === 1) {
|
||||
this.labelSource = newLabelSource[0];
|
||||
this.labelType = 'one-line';
|
||||
} else {
|
||||
this.labelSource = newLabelSource;
|
||||
this.labelType = 'two-line';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.labelType = 'empty';
|
||||
}
|
||||
|
||||
this.shift.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftShift | KeyModifiers.rightShift);
|
||||
this.control.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftCtrl | KeyModifiers.rightCtrl);
|
||||
this.option.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftAlt | KeyModifiers.rightAlt);
|
||||
this.command.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftGui | KeyModifiers.rightGui);
|
||||
|
||||
this.secondaryHeight = this.secondaryText ? this.height / 4 : 0;
|
||||
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
|
||||
|
||||
this.viewBox = [0, 0, this.width, this.height].join(' ');
|
||||
this.modifierIconNames.shift = this.mapper.getIcon('shift');
|
||||
this.modifierIconNames.option = this.mapper.getIcon('option');
|
||||
this.modifierIconNames.command = this.mapper.getIcon('command');
|
||||
|
||||
const bottomSideMode: boolean = this.width < this.height * 1.8;
|
||||
this.textContainer.y = 0;
|
||||
|
||||
const heightWidthRatio = this.height / this.width;
|
||||
this.secondaryTextWidth = this.width;
|
||||
|
||||
if (bottomSideMode) {
|
||||
const maxIconWidth = this.width / 4;
|
||||
@@ -75,7 +143,7 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
|
||||
const iconHeight = iconScalingFactor * maxIconHeight;
|
||||
this.modifierContainer.width = this.width;
|
||||
this.modifierContainer.height = this.height / 5;
|
||||
this.modifierContainer.y = this.height - this.modifierContainer.height;
|
||||
this.modifierContainer.y = this.height - this.modifierContainer.height - this.secondaryHeight;
|
||||
this.shift.width = iconWidth;
|
||||
this.shift.height = iconHeight;
|
||||
this.shift.x = (maxIconWidth - iconWidth) / 2;
|
||||
@@ -92,7 +160,7 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
|
||||
this.command.height = iconHeight;
|
||||
this.command.x = this.option.x + maxIconWidth;
|
||||
this.command.y = this.shift.y;
|
||||
this.textContainer.y = -this.modifierContainer.height / 2;
|
||||
this.textContainer.y = -this.modifierContainer.height / 2 - this.secondaryHeight / 2;
|
||||
} else {
|
||||
this.modifierContainer.width = this.width / 4;
|
||||
this.modifierContainer.height = this.height;
|
||||
@@ -120,40 +188,11 @@ export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
|
||||
this.command.x = this.option.x + this.width / 2;
|
||||
this.command.y = this.option.y;
|
||||
this.textContainer.x = -this.modifierContainer.width / 2;
|
||||
this.secondaryTextWidth = this.width - this.modifierContainer.width;
|
||||
}
|
||||
|
||||
this.textContainer.y -= textYModifier;
|
||||
this.textContainer.width = this.width;
|
||||
this.textContainer.height = this.height;
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
if (this.keystrokeAction.hasScancode()) {
|
||||
const scancode: number = this.keystrokeAction.scancode;
|
||||
this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode, this.keystrokeAction.type);
|
||||
if (this.labelSource) {
|
||||
this.labelType = 'icon';
|
||||
} else {
|
||||
let newLabelSource: string[];
|
||||
newLabelSource = this.mapper.scanCodeToText(scancode, this.keystrokeAction.type);
|
||||
if (newLabelSource) {
|
||||
if (newLabelSource.length === 1) {
|
||||
this.labelSource = newLabelSource[0];
|
||||
this.labelType = 'one-line';
|
||||
} else {
|
||||
this.labelSource = newLabelSource;
|
||||
this.labelType = 'two-line';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.labelType = 'empty';
|
||||
}
|
||||
|
||||
this.shift.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftShift | KeyModifiers.rightShift);
|
||||
this.control.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftCtrl | KeyModifiers.rightCtrl);
|
||||
this.option.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftAlt | KeyModifiers.rightAlt);
|
||||
this.command.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftGui | KeyModifiers.rightGui);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<svg:text
|
||||
<svg:text
|
||||
[attr.x]="0"
|
||||
[attr.y]="textY"
|
||||
[attr.text-anchor]="'middle'">
|
||||
<tspan [attr.x]="spanX" dy="0">{{ text }}</tspan>
|
||||
</svg:text>
|
||||
<tspan [attr.x]="spanX" dy="0">{{ text }}</tspan>
|
||||
</svg:text>
|
||||
<svg:g svg-secondary-role
|
||||
*ngIf="secondaryText"
|
||||
[height]="20"
|
||||
[width]="width"
|
||||
[y]="secondaryTextY"
|
||||
[text]="secondaryText">
|
||||
</svg:g>
|
||||
|
||||
|
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 316 B |
@@ -1,22 +1,43 @@
|
||||
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
|
||||
|
||||
import { isRectangleAsSecondaryRoleKey } from '../util';
|
||||
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
|
||||
|
||||
@Component({
|
||||
selector: 'g[svg-one-line-text-key]',
|
||||
templateUrl: './svg-one-line-text-key.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SvgOneLineTextKeyComponent implements OnInit {
|
||||
export class SvgOneLineTextKeyComponent implements OnChanges {
|
||||
@Input() height: number;
|
||||
@Input() width: number;
|
||||
@Input() text: string;
|
||||
@Input() secondaryText: string;
|
||||
|
||||
textY: number;
|
||||
spanX: number;
|
||||
secondaryTextY: number;
|
||||
secondaryHeight: number;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
this.textY = this.height / 2;
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.calculatePositions();
|
||||
}
|
||||
|
||||
calculatePositions() {
|
||||
let textYModifier = 0;
|
||||
let secondaryYModifier = 0;
|
||||
|
||||
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
|
||||
textYModifier = this.height / 5;
|
||||
secondaryYModifier = 5;
|
||||
}
|
||||
|
||||
this.textY = this.height / 2 - textYModifier;
|
||||
this.spanX = this.width / 2;
|
||||
|
||||
this.secondaryHeight = this.height / 4;
|
||||
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './svg-secondary-role.component';
|
||||
@@ -0,0 +1,15 @@
|
||||
<svg [attr.viewBox]="viewBox" [attr.width]="width" [attr.height]="height" [attr.y]="y">
|
||||
<g id="secondaryContent" [attr.transform]="transform">
|
||||
<svg viewBox="0 0 14 14" width="12" height="12" x="2" [attr.y]="textY / 3.5">
|
||||
<ellipse stroke="#fff" rx="6.5" ry="6.5" cy="7" cx="7" stroke-width="1" fill-opacity="0"/>
|
||||
<text text-anchor="start" font-family="Helvetica" font-size="12" y="7.8" x="4" stroke-width="0">2
|
||||
</text>
|
||||
</svg>
|
||||
<text [attr.y]="textY"
|
||||
[attr.x]="textIndent"
|
||||
font-size="12"
|
||||
text-anchor="start">
|
||||
{{ text }}
|
||||
</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 667 B |
@@ -0,0 +1,52 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
ElementRef,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
SimpleChanges,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
|
||||
import { getContentWidth } from '../../../../util';
|
||||
|
||||
const SECONDARY_STYLE: CSSStyleDeclaration = {
|
||||
font: '12px Helvetica'
|
||||
} as any;
|
||||
|
||||
@Component({
|
||||
selector: 'g[svg-secondary-role]',
|
||||
templateUrl: './svg-secondary-role.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SvgSecondaryRoleComponent implements OnInit, OnChanges {
|
||||
@Input() height: number;
|
||||
@Input() width: number;
|
||||
@Input() y: number;
|
||||
@Input() text: string;
|
||||
|
||||
@ViewChild('secondary') svgElement: ElementRef;
|
||||
|
||||
viewBox: string;
|
||||
textY: number;
|
||||
transform: string;
|
||||
textIndent = 16;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.viewBox = [0, 0, this.width, this.height].join(' ');
|
||||
this.textY = this.height / 2 - 2;
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.text) {
|
||||
this.calculateTextPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private calculateTextPosition(): void {
|
||||
const textWidth = getContentWidth(SECONDARY_STYLE, this.text) + this.textIndent;
|
||||
const translateValue = Math.max(0, (this.width - textWidth) / 2);
|
||||
this.transform = `translate(${ translateValue },0)`;
|
||||
}
|
||||
}
|
||||
@@ -4,3 +4,10 @@
|
||||
[attr.x]="svgWidth"
|
||||
[attr.y]="svgHeight">
|
||||
</svg:use>
|
||||
<svg:g svg-secondary-role
|
||||
*ngIf="secondaryText"
|
||||
[height]="20"
|
||||
[width]="width"
|
||||
[y]="secondaryTextY"
|
||||
[text]="secondaryText">
|
||||
</svg:g>
|
||||
|
||||
|
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 340 B |
@@ -1,22 +1,42 @@
|
||||
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
|
||||
|
||||
import { isRectangleAsSecondaryRoleKey } from '../util';
|
||||
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
|
||||
|
||||
@Component({
|
||||
selector: 'g[svg-single-icon-key]',
|
||||
templateUrl: './svg-single-icon-key.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SvgSingleIconKeyComponent implements OnInit {
|
||||
export class SvgSingleIconKeyComponent implements OnChanges {
|
||||
@Input() width: number;
|
||||
@Input() height: number;
|
||||
@Input() icon: string;
|
||||
@Input() secondaryText: string;
|
||||
|
||||
svgHeight: number;
|
||||
svgWidth: number;
|
||||
secondaryTextY: number;
|
||||
secondaryHeight: number;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.calculatePositions();
|
||||
}
|
||||
|
||||
calculatePositions(): void {
|
||||
let textYModifier = 0;
|
||||
let secondaryYModifier = 0;
|
||||
|
||||
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
|
||||
textYModifier = this.height / 5;
|
||||
secondaryYModifier = 5;
|
||||
}
|
||||
|
||||
this.svgWidth = this.width / 3;
|
||||
this.svgHeight = this.height / 3;
|
||||
this.secondaryHeight = this.height / 4;
|
||||
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,4 +9,11 @@
|
||||
[attr.height]="useHeight"
|
||||
[attr.x]="useX"
|
||||
[attr.y]="useY">
|
||||
</svg:use>
|
||||
</svg:use>
|
||||
<svg:g svg-secondary-role
|
||||
*ngIf="secondaryText"
|
||||
[height]="20"
|
||||
[width]="width"
|
||||
[y]="secondaryTextY"
|
||||
[text]="secondaryText">
|
||||
</svg:g>
|
||||
|
||||
|
Before Width: | Height: | Size: 309 B After Width: | Height: | Size: 484 B |
@@ -1,15 +1,19 @@
|
||||
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, Input, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
|
||||
|
||||
import { isRectangleAsSecondaryRoleKey } from '../util';
|
||||
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
|
||||
|
||||
@Component({
|
||||
selector: 'g[svg-text-icon-key]',
|
||||
templateUrl: './svg-text-icon-key.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SvgTextIconKeyComponent implements OnInit {
|
||||
export class SvgTextIconKeyComponent implements OnChanges {
|
||||
@Input() width: number;
|
||||
@Input() height: number;
|
||||
@Input() text: string;
|
||||
@Input() icon: string;
|
||||
@Input() secondaryText: string;
|
||||
|
||||
useWidth: number;
|
||||
useHeight: number;
|
||||
@@ -18,16 +22,33 @@ export class SvgTextIconKeyComponent implements OnInit {
|
||||
textY: number;
|
||||
textAnchor: string;
|
||||
spanX: number;
|
||||
secondaryTextY: number;
|
||||
secondaryHeight: number;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.calculatePositions();
|
||||
}
|
||||
|
||||
calculatePositions(): void {
|
||||
let textYModifier = 0;
|
||||
let secondaryYModifier = 0;
|
||||
|
||||
if (this.secondaryText && isRectangleAsSecondaryRoleKey(this.width, this.height)) {
|
||||
textYModifier = this.height / 5;
|
||||
secondaryYModifier = 5;
|
||||
}
|
||||
|
||||
this.useWidth = this.width / 3;
|
||||
this.useHeight = this.height / 3;
|
||||
this.useX = (this.width > 2 * this.height) ? this.width * 0.6 : this.width / 3;
|
||||
this.useY = (this.width > 2 * this.height) ? this.height / 3 : this.height / 2;
|
||||
this.textY = (this.width > 2 * this.height) ? this.height / 2 : this.height / 3;
|
||||
this.textY = ((this.width > 2 * this.height) ? this.height / 2 : this.height / 3) - textYModifier;
|
||||
this.textAnchor = (this.width > 2 * this.height) ? 'end' : 'middle';
|
||||
this.spanX = (this.width > 2 * this.height) ? 0.6 * this.width : this.width / 2;
|
||||
|
||||
this.secondaryHeight = this.height / 4;
|
||||
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,11 @@
|
||||
[attr.y]="spanYs[index]"
|
||||
dy="0"
|
||||
>{{ text }}</tspan>
|
||||
</svg:text>
|
||||
</svg:text>
|
||||
<svg:g svg-secondary-role
|
||||
*ngIf="secondaryText"
|
||||
[height]="20"
|
||||
[width]="width"
|
||||
[y]="secondaryTextY"
|
||||
[text]="secondaryText">
|
||||
</svg:g>
|
||||
|
||||
|
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 474 B |
@@ -1,28 +1,51 @@
|
||||
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, Input, ChangeDetectionStrategy, SimpleChanges, OnChanges } from '@angular/core';
|
||||
import { SECONDARY_ROLE_BOTTOM_MARGIN } from '../../constants';
|
||||
|
||||
@Component({
|
||||
selector: 'g[svg-two-line-text-key]',
|
||||
templateUrl: './svg-two-line-text-key.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SvgTwoLineTextKeyComponent implements OnInit {
|
||||
export class SvgTwoLineTextKeyComponent implements OnChanges {
|
||||
@Input() height: number;
|
||||
@Input() width: number;
|
||||
@Input() texts: string[];
|
||||
@Input() secondaryText: string;
|
||||
|
||||
textY: number;
|
||||
spanX: number;
|
||||
spanYs: number[];
|
||||
secondaryTextY: number;
|
||||
secondaryHeight: number;
|
||||
|
||||
constructor() {
|
||||
this.spanYs = [];
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.textY = this.height / 2;
|
||||
this.spanX = this.width / 2;
|
||||
for (let i = 0; i < this.texts.length; ++i) {
|
||||
this.spanYs.push((0.75 - i * 0.5) * this.height);
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.calculatePositions();
|
||||
}
|
||||
|
||||
calculatePositions(): void {
|
||||
let textYModifier = 0;
|
||||
let secondaryYModifier = 0;
|
||||
this.secondaryHeight = 0;
|
||||
let textContainerHeight = this.height;
|
||||
|
||||
if (this.secondaryText) {
|
||||
textYModifier = this.height / 5;
|
||||
secondaryYModifier = 0;
|
||||
this.secondaryHeight = this.height / 4;
|
||||
textContainerHeight -= this.secondaryHeight;
|
||||
}
|
||||
|
||||
this.textY = textContainerHeight / 2;
|
||||
this.spanX = this.width / 2;
|
||||
this.spanYs = [];
|
||||
for (let i = 0; i < this.texts.length; ++i) {
|
||||
this.spanYs.push((0.75 - i * 0.5) * textContainerHeight);
|
||||
}
|
||||
|
||||
this.secondaryTextY = this.height - this.secondaryHeight - SECONDARY_ROLE_BOTTOM_MARGIN - secondaryYModifier;
|
||||
}
|
||||
}
|
||||
|
||||
3
packages/uhk-web/src/app/components/svg/keys/util.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const isRectangleAsSecondaryRoleKey = (width: number, height: number): boolean => {
|
||||
return width > height * 2.4;
|
||||
};
|
||||
@@ -5,7 +5,7 @@ import { SvgKeyboardKey } from '../keys';
|
||||
import {
|
||||
SvgKeyCaptureEvent,
|
||||
SvgKeyClickEvent,
|
||||
SvgModuleCaptureEvent,
|
||||
SvgModuleCaptureEvent,
|
||||
SvgModuleKeyClickEvent
|
||||
} from '../../../models/svg-key-events';
|
||||
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
[currentKeymap]="keymap"
|
||||
[currentLayer]="currentLayer"
|
||||
[allowLayerDoubleTap]="allowLayerDoubleTap"
|
||||
[remapOnAllKeymap]="remapOnAllKeymap"
|
||||
[remapOnAllLayer]="remapOnAllLayer"
|
||||
[remapInfo]="remapInfo"
|
||||
(cancel)="hidePopover()"
|
||||
(remap)="onRemap($event)"></popover>
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ import {
|
||||
SvgKeyboardKeyClickEvent,
|
||||
SvgKeyHoverEvent
|
||||
} from '../../../models/svg-key-events';
|
||||
import { RemapInfo } from '../../../models/remap-info';
|
||||
import { mapLeftRigthModifierToKeyActionModifier } from '../../../util';
|
||||
|
||||
interface NameValuePair {
|
||||
name: string;
|
||||
@@ -87,8 +89,10 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
|
||||
layers: Layer[];
|
||||
keyPosition: ClientRect;
|
||||
wrapPosition: ClientRect;
|
||||
remapOnAllKeymap: boolean;
|
||||
remapOnAllLayer: boolean;
|
||||
remapInfo: RemapInfo = {
|
||||
remapOnAllKeymap: false,
|
||||
remapOnAllLayer: false
|
||||
};
|
||||
|
||||
private wrapHost: HTMLElement;
|
||||
private keyElement: HTMLElement;
|
||||
@@ -156,8 +160,10 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
|
||||
this.selectedKey = {layerId: this.currentLayer, moduleId: event.moduleId, keyId: event.keyId};
|
||||
const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[event.moduleId].keyActions[event.keyId];
|
||||
this.keyElement = event.keyTarget;
|
||||
this.remapOnAllKeymap = event.shiftPressed;
|
||||
this.remapOnAllLayer = event.altPressed;
|
||||
this.remapInfo = {
|
||||
remapOnAllKeymap: event.shiftPressed,
|
||||
remapOnAllLayer: event.altPressed
|
||||
};
|
||||
this.showPopover(keyActionToEdit);
|
||||
}
|
||||
}
|
||||
@@ -176,14 +182,9 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
|
||||
|
||||
onCapture(event: SvgKeyboardCaptureEvent): void {
|
||||
const keystrokeAction: KeystrokeAction = new KeystrokeAction();
|
||||
const modifiers = event.captured.left.concat(event.captured.right).map(x => x ? 1 : 0);
|
||||
|
||||
keystrokeAction.scancode = event.captured.code;
|
||||
keystrokeAction.modifierMask = 0;
|
||||
|
||||
for (let i = 0; i < modifiers.length; ++i) {
|
||||
keystrokeAction.modifierMask |= modifiers[i] << this.mapper.modifierMapper(i);
|
||||
}
|
||||
keystrokeAction.modifierMask = mapLeftRigthModifierToKeyActionModifier(event.captured.left, event.captured.right);
|
||||
|
||||
this.store.dispatch(
|
||||
KeymapActions.saveKey(
|
||||
|
||||
7
packages/uhk-web/src/app/models/key-modifier-model.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { KeyModifiers } from 'uhk-common';
|
||||
|
||||
export interface KeyModifierModel {
|
||||
text: string;
|
||||
value: KeyModifiers;
|
||||
checked: boolean;
|
||||
}
|
||||
5
packages/uhk-web/src/app/models/operating-system.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export enum OperatingSystem {
|
||||
Linux,
|
||||
Mac,
|
||||
Windows
|
||||
}
|
||||
4
packages/uhk-web/src/app/models/remap-info.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface RemapInfo {
|
||||
remapOnAllKeymap: boolean;
|
||||
remapOnAllLayer: boolean;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { KeyModifierModel } from './key-modifier-model';
|
||||
|
||||
export interface SvgKeyClickEvent {
|
||||
keyTarget: HTMLElement;
|
||||
shiftPressed?: boolean;
|
||||
@@ -14,8 +16,8 @@ export interface SvgKeyboardKeyClickEvent extends SvgModuleKeyClickEvent {
|
||||
|
||||
export interface KeyCaptureData {
|
||||
code: number;
|
||||
left: boolean[];
|
||||
right: boolean[];
|
||||
left: KeyModifierModel[];
|
||||
right: KeyModifierModel[];
|
||||
}
|
||||
|
||||
export interface SvgKeyCaptureEvent {
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { MapperService } from './mapper.service';
|
||||
import { KeyModifiers } from 'uhk-common';
|
||||
import { KeyModifierModel } from '../models/key-modifier-model';
|
||||
|
||||
@Injectable()
|
||||
export class CaptureService {
|
||||
private mapping: Map<number, number>;
|
||||
private leftModifiers: Map<number, boolean>;
|
||||
private rightModifiers: Map<number, boolean>;
|
||||
private readonly leftModifiers: Map<number, KeyModifierModel>;
|
||||
private readonly rightModifiers: Map<number, KeyModifierModel>;
|
||||
|
||||
constructor() {
|
||||
this.leftModifiers = new Map<number, boolean>();
|
||||
this.rightModifiers = new Map<number, boolean>();
|
||||
constructor(private mapper: MapperService) {
|
||||
this.leftModifiers = new Map<number, KeyModifierModel>();
|
||||
this.rightModifiers = new Map<number, KeyModifierModel>();
|
||||
this.mapping = new Map<number, number>();
|
||||
}
|
||||
|
||||
@@ -21,26 +25,61 @@ export class CaptureService {
|
||||
}
|
||||
|
||||
public setModifier(left: boolean, code: number) {
|
||||
return left ? this.leftModifiers.set(code, true) : this.rightModifiers.set(code, true);
|
||||
const map = left ? this.leftModifiers : this.rightModifiers;
|
||||
map.get(code).checked = true;
|
||||
}
|
||||
|
||||
public getModifiers(left: boolean) {
|
||||
return left ? this.reMap(this.leftModifiers) : this.reMap(this.rightModifiers);
|
||||
const map = left ? this.leftModifiers : this.rightModifiers;
|
||||
|
||||
return Array.from(map.values());
|
||||
}
|
||||
|
||||
public initModifiers() {
|
||||
this.leftModifiers.set(16, false); // Shift
|
||||
this.leftModifiers.set(17, false); // Ctrl
|
||||
this.leftModifiers.set(18, false); // Alt
|
||||
this.leftModifiers.set(91, false); // Super
|
||||
this.leftModifiers.set(16, {
|
||||
text: 'LShift',
|
||||
value: KeyModifiers.leftShift,
|
||||
checked: false
|
||||
});
|
||||
this.leftModifiers.set(17, {
|
||||
text: 'LCtrl',
|
||||
value: KeyModifiers.leftCtrl,
|
||||
checked: false
|
||||
});
|
||||
this.leftModifiers.set(18, {
|
||||
text: this.mapper.getOsSpecificText('LAlt'),
|
||||
value: KeyModifiers.leftAlt,
|
||||
checked: false
|
||||
});
|
||||
this.leftModifiers.set(91, {
|
||||
text: this.mapper.getOsSpecificText('LSuper'),
|
||||
value: KeyModifiers.leftGui,
|
||||
checked: false
|
||||
});
|
||||
|
||||
this.rightModifiers.set(16, false); // Shift
|
||||
this.rightModifiers.set(17, false); // Ctrl
|
||||
this.rightModifiers.set(18, false); // Alt
|
||||
this.rightModifiers.set(91, false); // Super
|
||||
this.rightModifiers.set(16, {
|
||||
text: 'RShift',
|
||||
value: KeyModifiers.rightShift,
|
||||
checked: false
|
||||
});
|
||||
this.rightModifiers.set(17, {
|
||||
text: 'RCtrl',
|
||||
value: KeyModifiers.rightCtrl,
|
||||
checked: false
|
||||
});
|
||||
this.rightModifiers.set(18, {
|
||||
text: this.mapper.getOsSpecificText('RAlt'),
|
||||
value: KeyModifiers.rightAlt,
|
||||
checked: false
|
||||
});
|
||||
this.rightModifiers.set(91, {
|
||||
text: this.mapper.getOsSpecificText('RSuper'),
|
||||
value: KeyModifiers.rightGui,
|
||||
checked: false
|
||||
});
|
||||
}
|
||||
|
||||
public populateMapping () {
|
||||
public populateMapping() {
|
||||
this.mapping.set(8, 42); // Backspace
|
||||
this.mapping.set(9, 43); // Tab
|
||||
this.mapping.set(13, 40); // Enter
|
||||
@@ -136,8 +175,4 @@ export class CaptureService {
|
||||
this.mapping.set(221, 48); // Close bracket
|
||||
this.mapping.set(222, 52); // Single quote
|
||||
}
|
||||
|
||||
private reMap(value: Map<number, boolean>): boolean[] {
|
||||
return [value.get(16), value.get(17), value.get(91), value.get(18)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,40 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { KeystrokeType } from 'uhk-common';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { KeyModifiers, KeystrokeType, SecondaryRoleAction } from 'uhk-common';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
import { AppState, getOperatingSystem } from '../store';
|
||||
import { OperatingSystem } from '../models/operating-system';
|
||||
import { KeyModifierModel } from '../models/key-modifier-model';
|
||||
|
||||
@Injectable()
|
||||
export class MapperService {
|
||||
|
||||
private basicScanCodeTextMap: Map<number, string[]>;
|
||||
private mediaScanCodeTextMap: Map<number, string[]>;
|
||||
private sytemScanCodeTextMap: Map<number, string[]>;
|
||||
private systemScanCodeTextMap: Map<number, string[]>;
|
||||
|
||||
private basicScancodeIcons: Map<number, string>;
|
||||
private mediaScancodeIcons: Map<number, string>;
|
||||
private systemScancodeIcons: Map<number, string>;
|
||||
private nameToFileName: Map<string, string>;
|
||||
private osSpecificTexts: Map<string, string>;
|
||||
private secondaryRoleTexts: Map<number, string>;
|
||||
|
||||
constructor() {
|
||||
this.initScanCodeTextMap();
|
||||
this.initScancodeIcons();
|
||||
this.initNameToFileNames();
|
||||
private operatingSystem: OperatingSystem;
|
||||
private osSubscription: Subscription;
|
||||
|
||||
constructor(private store: Store<AppState>) {
|
||||
this.osSubscription = store
|
||||
.select(getOperatingSystem)
|
||||
.subscribe(os => {
|
||||
this.operatingSystem = os;
|
||||
this.initOsSpecificText();
|
||||
this.initScanCodeTextMap();
|
||||
this.initScancodeIcons();
|
||||
this.initNameToFileNames();
|
||||
this.initSecondaryRoleTexts();
|
||||
});
|
||||
}
|
||||
|
||||
public scanCodeToText(scanCode: number, type: KeystrokeType = KeystrokeType.basic): string[] {
|
||||
@@ -27,7 +45,7 @@ export class MapperService {
|
||||
map = this.mediaScanCodeTextMap;
|
||||
break;
|
||||
case KeystrokeType.system:
|
||||
map = this.sytemScanCodeTextMap;
|
||||
map = this.systemScanCodeTextMap;
|
||||
break;
|
||||
default:
|
||||
map = this.basicScanCodeTextMap;
|
||||
@@ -79,7 +97,10 @@ export class MapperService {
|
||||
}
|
||||
|
||||
public getIcon(iconName: string): string {
|
||||
return 'assets/compiled_sprite.svg#' + this.nameToFileName.get(iconName);
|
||||
const mappedIconName = this.nameToFileName.get(iconName);
|
||||
if (mappedIconName) {
|
||||
return 'assets/compiled_sprite.svg#' + mappedIconName;
|
||||
}
|
||||
}
|
||||
|
||||
public modifierMapper(x: number) {
|
||||
@@ -90,6 +111,87 @@ export class MapperService {
|
||||
}
|
||||
}
|
||||
|
||||
public getOperatingSystem(): OperatingSystem {
|
||||
return this.operatingSystem;
|
||||
}
|
||||
|
||||
public getOsSpecificText(key: string): string {
|
||||
const text = this.osSpecificTexts.get(key);
|
||||
|
||||
return text ? text : key;
|
||||
}
|
||||
|
||||
public getSecondaryRoleText(secondaryRoleAction: SecondaryRoleAction): string {
|
||||
return this.secondaryRoleTexts.get(secondaryRoleAction);
|
||||
}
|
||||
|
||||
public getLeftKeyModifiers(): KeyModifierModel[] {
|
||||
return [
|
||||
{
|
||||
text: 'LShift',
|
||||
value: KeyModifiers.leftShift,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
text: 'LCtrl',
|
||||
value: KeyModifiers.leftCtrl,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
text: this.getOsSpecificText('LAlt'),
|
||||
value: KeyModifiers.leftAlt,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
text: this.getOsSpecificText('LSuper'),
|
||||
value: KeyModifiers.leftGui,
|
||||
checked: false
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
public getRightKeyModifiers(): KeyModifierModel[] {
|
||||
return [
|
||||
{
|
||||
text: 'RShift',
|
||||
value: KeyModifiers.rightShift,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
text: 'RCtrl',
|
||||
value: KeyModifiers.rightCtrl,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
text: this.getOsSpecificText('RAlt'),
|
||||
value: KeyModifiers.rightAlt,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
text: this.getOsSpecificText('RSuper'),
|
||||
value: KeyModifiers.rightGui,
|
||||
checked: false
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
private initOsSpecificText(): void {
|
||||
this.osSpecificTexts = new Map<string, string>();
|
||||
|
||||
if (this.operatingSystem === OperatingSystem.Mac) {
|
||||
this.osSpecificTexts.set('Enter', 'Return');
|
||||
this.osSpecificTexts.set('Alt', 'Option');
|
||||
this.osSpecificTexts.set('Super', 'Cmd');
|
||||
this.osSpecificTexts.set('LSuper', 'LCmd');
|
||||
this.osSpecificTexts.set('RSuper', 'RCmd');
|
||||
this.osSpecificTexts.set('LAlt', 'LOption');
|
||||
this.osSpecificTexts.set('RAlt', 'ROption');
|
||||
} else if (this.operatingSystem === OperatingSystem.Windows) {
|
||||
this.osSpecificTexts.set('LSuper', 'LWindows');
|
||||
this.osSpecificTexts.set('RSuper', 'RWindows');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: read the mapping from JSON
|
||||
private initScanCodeTextMap(): void {
|
||||
this.basicScanCodeTextMap = new Map<number, string[]>();
|
||||
@@ -129,7 +231,7 @@ export class MapperService {
|
||||
this.basicScanCodeTextMap.set(37, ['8', '*']);
|
||||
this.basicScanCodeTextMap.set(38, ['9', '(']);
|
||||
this.basicScanCodeTextMap.set(39, ['0', ')']);
|
||||
this.basicScanCodeTextMap.set(40, ['Enter']);
|
||||
this.basicScanCodeTextMap.set(40, [this.getOsSpecificText('Enter')]);
|
||||
this.basicScanCodeTextMap.set(41, ['Esc']);
|
||||
this.basicScanCodeTextMap.set(42, ['Backspace']);
|
||||
this.basicScanCodeTextMap.set(43, ['Tab']);
|
||||
@@ -177,7 +279,7 @@ export class MapperService {
|
||||
this.basicScanCodeTextMap.set(85, ['*']);
|
||||
this.basicScanCodeTextMap.set(86, ['-']);
|
||||
this.basicScanCodeTextMap.set(87, ['+']);
|
||||
this.basicScanCodeTextMap.set(88, ['Enter']);
|
||||
this.basicScanCodeTextMap.set(88, [this.getOsSpecificText('Enter')]);
|
||||
this.basicScanCodeTextMap.set(89, ['end', '1']);
|
||||
this.basicScanCodeTextMap.set(90, ['2']);
|
||||
this.basicScanCodeTextMap.set(91, ['pgdn', '3']);
|
||||
@@ -224,10 +326,10 @@ export class MapperService {
|
||||
this.mediaScanCodeTextMap.set(394, ['Launch Email Client']);
|
||||
this.mediaScanCodeTextMap.set(402, ['Launch Calculator']);
|
||||
|
||||
this.sytemScanCodeTextMap = new Map<number, string[]>();
|
||||
this.sytemScanCodeTextMap.set(129, ['Power Down']);
|
||||
this.sytemScanCodeTextMap.set(130, ['Sleep']);
|
||||
this.sytemScanCodeTextMap.set(131, ['Wake Up']);
|
||||
this.systemScanCodeTextMap = new Map<number, string[]>();
|
||||
this.systemScanCodeTextMap.set(129, ['Power Down']);
|
||||
this.systemScanCodeTextMap.set(130, ['Sleep']);
|
||||
this.systemScanCodeTextMap.set(131, ['Wake Up']);
|
||||
}
|
||||
|
||||
private initScancodeIcons(): void {
|
||||
@@ -266,8 +368,12 @@ export class MapperService {
|
||||
this.nameToFileName.set('switch-keymap', 'icon-kbd__mod--switch-keymap');
|
||||
this.nameToFileName.set('macro', 'icon-icon__macro');
|
||||
this.nameToFileName.set('shift', 'icon-kbd__default--modifier-shift');
|
||||
this.nameToFileName.set('option', 'icon-kbd__default--modifier-option');
|
||||
this.nameToFileName.set('command', 'icon-kbd__default--modifier-command');
|
||||
if (this.operatingSystem === OperatingSystem.Mac) {
|
||||
this.nameToFileName.set('option', 'icon-kbd__default--modifier-option');
|
||||
this.nameToFileName.set('command', 'icon-kbd__default--modifier-command');
|
||||
} else if (this.operatingSystem === OperatingSystem.Windows) {
|
||||
this.nameToFileName.set('command', 'icon-kbd__default--modifier-windows');
|
||||
}
|
||||
this.nameToFileName.set('mouse', 'icon-kbd__mouse');
|
||||
this.nameToFileName.set('left-arrow', 'icon-kbd__mod--arrow-left');
|
||||
this.nameToFileName.set('right-arrow', 'icon-kbd__mod--arrow-right');
|
||||
@@ -279,4 +385,18 @@ export class MapperService {
|
||||
this.nameToFileName.set('scroll-up', 'icon-kbd__mouse--scroll-up');
|
||||
}
|
||||
|
||||
private initSecondaryRoleTexts(): void {
|
||||
this.secondaryRoleTexts = new Map<number, string>();
|
||||
this.secondaryRoleTexts.set(0, 'LCtrl');
|
||||
this.secondaryRoleTexts.set(1, 'LShift');
|
||||
this.secondaryRoleTexts.set(2, 'LAlt');
|
||||
this.secondaryRoleTexts.set(3, 'LSuper');
|
||||
this.secondaryRoleTexts.set(4, 'RCtrl');
|
||||
this.secondaryRoleTexts.set(5, 'RShift');
|
||||
this.secondaryRoleTexts.set(6, 'RAlt');
|
||||
this.secondaryRoleTexts.set(7, 'RSuper');
|
||||
this.secondaryRoleTexts.set(8, 'Mod');
|
||||
this.secondaryRoleTexts.set(9, 'Fn');
|
||||
this.secondaryRoleTexts.set(10, 'Mouse');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,7 +888,11 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 32
|
||||
},
|
||||
null,
|
||||
{
|
||||
"keyActionType": "mouse",
|
||||
@@ -959,7 +963,11 @@
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 2
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -1875,7 +1883,11 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 32
|
||||
},
|
||||
null,
|
||||
{
|
||||
"keyActionType": "mouse",
|
||||
@@ -1946,7 +1958,11 @@
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 2
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -2856,7 +2872,11 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 32
|
||||
},
|
||||
null,
|
||||
{
|
||||
"keyActionType": "mouse",
|
||||
@@ -2921,7 +2941,11 @@
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 2
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -3840,7 +3864,11 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 32
|
||||
},
|
||||
null,
|
||||
{
|
||||
"keyActionType": "mouse",
|
||||
@@ -3905,7 +3933,11 @@
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 2
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -4809,7 +4841,11 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 32
|
||||
},
|
||||
null,
|
||||
{
|
||||
"keyActionType": "mouse",
|
||||
@@ -4874,7 +4910,11 @@
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 2
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -5790,7 +5830,11 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 32
|
||||
},
|
||||
null,
|
||||
{
|
||||
"keyActionType": "mouse",
|
||||
@@ -5855,7 +5899,11 @@
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 2
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -6755,7 +6803,11 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 32
|
||||
},
|
||||
null,
|
||||
{
|
||||
"keyActionType": "mouse",
|
||||
@@ -6816,7 +6868,11 @@
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"modifierMask": 2
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
@@ -6903,4 +6959,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ import {
|
||||
SvgMouseScrollKeyComponent,
|
||||
SvgMouseSpeedKeyComponent,
|
||||
SvgOneLineTextKeyComponent,
|
||||
SvgSecondaryRoleComponent,
|
||||
SvgSingleIconKeyComponent,
|
||||
SvgSwitchKeymapKeyComponent,
|
||||
SvgTextIconKeyComponent,
|
||||
@@ -186,7 +187,8 @@ import { HelpPageComponent } from './components/agent/help-page/help-page.compon
|
||||
FileUploadComponent,
|
||||
AutoGrowInputComponent,
|
||||
HelpPageComponent,
|
||||
ExternalUrlDirective
|
||||
ExternalUrlDirective,
|
||||
SvgSecondaryRoleComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
||||
@@ -10,6 +10,7 @@ import * as fromAppUpdate from './reducers/app-update.reducer';
|
||||
import * as autoUpdateSettings from './reducers/auto-update-settings';
|
||||
import * as fromApp from './reducers/app.reducer';
|
||||
import * as fromDevice from './reducers/device';
|
||||
import * as fromSelectors from './reducers/selectors';
|
||||
import { initProgressButtonState } from './reducers/progress-button-state';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { RouterStateUrl } from './router-util';
|
||||
@@ -52,6 +53,7 @@ export const getKeyboardLayout = createSelector(appState, fromApp.getKeyboardLay
|
||||
export const deviceConfigurationLoaded = createSelector(appState, fromApp.deviceConfigurationLoaded);
|
||||
export const getAgentVersionInfo = createSelector(appState, fromApp.getAgentVersionInfo);
|
||||
export const getPrivilegePageState = createSelector(appState, fromApp.getPrivilagePageState);
|
||||
export const getOperatingSystem = createSelector(appState, fromSelectors.getOperatingSystem);
|
||||
export const runningOnNotSupportedWindows = createSelector(appState, fromApp.runningOnNotSupportedWindows);
|
||||
export const firmwareUpgradeAllowed = createSelector(runningOnNotSupportedWindows, notSupportedOs => !notSupportedOs);
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { OperatingSystem } from '../../models/operating-system';
|
||||
import { State } from './app.reducer';
|
||||
|
||||
export const getOperatingSystem = (state: State): OperatingSystem => {
|
||||
if (state.runningInElectron) {
|
||||
switch (state.platform) {
|
||||
case 'darwin':
|
||||
return OperatingSystem.Mac;
|
||||
|
||||
case 'win32':
|
||||
return OperatingSystem.Windows;
|
||||
|
||||
default:
|
||||
return OperatingSystem.Linux;
|
||||
}
|
||||
}
|
||||
|
||||
const platform = navigator.platform.toLowerCase();
|
||||
|
||||
if (platform.indexOf('mac') > -1) {
|
||||
return OperatingSystem.Mac;
|
||||
}
|
||||
|
||||
if (platform.indexOf('win') > -1) {
|
||||
return OperatingSystem.Windows;
|
||||
}
|
||||
|
||||
return OperatingSystem.Linux;
|
||||
};
|
||||
1
packages/uhk-web/src/app/store/reducers/selectors.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './get-operating-system.selector';
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './find-new-item';
|
||||
export * from './html-helper';
|
||||
export * from './key-modifier-model-mapper';
|
||||
export * from './validators';
|
||||
export * from './version-helper';
|
||||
|
||||
13
packages/uhk-web/src/app/util/key-modifier-model-mapper.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { KeyModifierModel } from '../models/key-modifier-model';
|
||||
|
||||
export const mapLeftRigthModifierToKeyActionModifier = (left: KeyModifierModel[], right: KeyModifierModel[]): number => {
|
||||
const modifiers = [...left, ...right];
|
||||
let result = 0;
|
||||
for (const modifier of modifiers) {
|
||||
if (modifier.checked) {
|
||||
result |= modifier.value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
@@ -1,4 +1,8 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
$grid-gutter-width: 30px;
|
||||
$zindex-navbar-fixed: 1030;
|
||||
@import '~spacing-bootstrap-3/spacing';
|
||||
|
||||
@import './styles/variables';
|
||||
@import '~angular-notifier/styles';
|
||||
@import '~font-awesome/scss/font-awesome';
|
||||
|
||||
@@ -4,6 +4,10 @@ ngx-select,
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
input.input-sm {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.dropdown-header {
|
||||
font-weight: bold;
|
||||
font-size: 1em;
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
#!/usr/bin/env node
|
||||
const uhk = require('./uhk');
|
||||
const device = uhk.getUhkDevice();
|
||||
|
||||
const eepromTransferType = process.argv[2];
|
||||
const eepromTransfer = uhk.eepromTransfer[eepromTransferType];
|
||||
(async function() {
|
||||
const operationArg = process.argv[2];
|
||||
const operation = uhk.eepromOperations[operationArg];
|
||||
if (operation === undefined) {
|
||||
console.error(`Invalid operation: Gotta provide one of ${Object.keys(uhk.eepromOperations).join(', ')}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (eepromTransfer === undefined) {
|
||||
console.error(`Gotta provide one of ${Object.keys(uhk.eepromTransfer).join(', ')}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// const buffer = await uhk.writeDevice(device, [uhk.usbCommands.launchEepromTransfer, eepromTransfer.operation, eepromTransfer.configBuffer]);
|
||||
const bufferIdArg = process.argv[3];
|
||||
const bufferId = uhk.configBufferIds[bufferIdArg]
|
||||
if (bufferId === undefined) {
|
||||
console.error(`Invalid bufferId: Gotta provide one of ${Object.keys(uhk.configBufferIds).join(', ')}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const buffer = await uhk.launchEepromTransfer(device, operation, bufferId);
|
||||
})();
|
||||
|
||||
@@ -14,11 +14,11 @@ let prevGeneric, prevBasic, prevMedia, prevSystem, prevMouse;
|
||||
function getDebugInfo() {
|
||||
|
||||
const payload = new Buffer([uhk.usbCommands.getDebugBuffer]);
|
||||
console.log(payload)
|
||||
console.log('Sending ', uhk.bufferToString(payload));
|
||||
// console.log(payload)
|
||||
// console.log('Sending ', uhk.bufferToString(payload));
|
||||
device.write(uhk.getTransferData(payload));
|
||||
const rxBuffer = Buffer.from(device.readSync());
|
||||
console.log('Received', uhk.bufferToString(rxBuffer));
|
||||
// console.log('Received', uhk.bufferToString(rxBuffer));
|
||||
|
||||
const I2C_Watchdog = getUint32(rxBuffer, 1);
|
||||
const I2cSlaveScheduler_Counter = getUint32(rxBuffer, 5);
|
||||
@@ -33,25 +33,25 @@ function getDebugInfo() {
|
||||
const UsbSystemKeyboardActionCounter = getUint32(rxBuffer, 41);
|
||||
const UsbMouseActionCounter = getUint32(rxBuffer, 45);
|
||||
|
||||
process.stdout.write(`I2C_Watchdog:${I2C_Watchdog} | `);
|
||||
process.stdout.write(`I2cSlaveScheduler_Counter:${I2cSlaveScheduler_Counter} | `);
|
||||
process.stdout.write(`I2cWatchdog_WatchCounter:${I2cWatchdog_WatchCounter} | `);
|
||||
process.stdout.write(`I2cWatchdog_RecoveryCounter:${I2cWatchdog_RecoveryCounter} | `);
|
||||
process.stdout.write(`KeyScannerCounter:${KeyScannerCounter} | `);
|
||||
process.stdout.write(`UsbReportUpdateCounter:${UsbReportUpdateCounter} | `);
|
||||
process.stdout.write(`CurrentTime:${CurrentTime} | `);
|
||||
process.stdout.write(`UsbGenericHidActionCounter:${UsbGenericHidActionCounter} | `);
|
||||
process.stdout.write(`UsbBasicKeyboardActionCounter:${UsbBasicKeyboardActionCounter} | `);
|
||||
process.stdout.write(`UsbMediaKeyboardActionCounter:${UsbMediaKeyboardActionCounter} | `);
|
||||
process.stdout.write(`UsbSystemKeyboardActionCounter:${UsbSystemKeyboardActionCounter} | `);
|
||||
process.stdout.write(`UsbMouseActionCounter:${UsbMouseActionCounter} | `);
|
||||
process.stdout.write(`I2cWatchdog:${I2C_Watchdog} | `);
|
||||
process.stdout.write(`I2cSlave:${I2cSlaveScheduler_Counter} | `);
|
||||
process.stdout.write(`I2cWatch:${I2cWatchdog_WatchCounter} | `);
|
||||
process.stdout.write(`I2cRecovery:${I2cWatchdog_RecoveryCounter} | `);
|
||||
process.stdout.write(`KeyMatrix:${KeyScannerCounter} | `);
|
||||
process.stdout.write(`UsbReport:${UsbReportUpdateCounter} | `);
|
||||
process.stdout.write(`Time:${CurrentTime} | `);
|
||||
process.stdout.write(`UsbGeneric:${UsbGenericHidActionCounter} | `);
|
||||
process.stdout.write(`UsbBasic:${UsbBasicKeyboardActionCounter} | `);
|
||||
process.stdout.write(`UsbMedia:${UsbMediaKeyboardActionCounter} | `);
|
||||
process.stdout.write(`UsbSystem:${UsbSystemKeyboardActionCounter} | `);
|
||||
process.stdout.write(`UsbMouse:${UsbMouseActionCounter}`);
|
||||
process.stdout.write('\n');
|
||||
|
||||
process.stdout.write(`generic:${UsbGenericHidActionCounter - prevGeneric} `)
|
||||
process.stdout.write(`basic:${UsbBasicKeyboardActionCounter - prevBasic} `)
|
||||
process.stdout.write(`basic:${UsbMediaKeyboardActionCounter - prevMedia} `)
|
||||
process.stdout.write(`basic:${UsbSystemKeyboardActionCounter - prevSystem} `)
|
||||
process.stdout.write(`basic:${UsbMouseActionCounter - prevMouse} `)
|
||||
// process.stdout.write(`generic:${UsbGenericHidActionCounter - prevGeneric} `)
|
||||
// process.stdout.write(`basic:${UsbBasicKeyboardActionCounter - prevBasic} `)
|
||||
// process.stdout.write(`basic:${UsbMediaKeyboardActionCounter - prevMedia} `)
|
||||
// process.stdout.write(`basic:${UsbSystemKeyboardActionCounter - prevSystem} `)
|
||||
// process.stdout.write(`basic:${UsbMouseActionCounter - prevMouse} `)
|
||||
|
||||
prevGeneric = UsbGenericHidActionCounter;
|
||||
prevBasic = UsbBasicKeyboardActionCounter;
|
||||
|
||||
14
packages/usb/package-lock.json
generated
@@ -1,11 +1,14 @@
|
||||
{
|
||||
"requires": true,
|
||||
"name": "agent-usb",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "8.0.28",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.28.tgz",
|
||||
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ=="
|
||||
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
@@ -241,7 +244,8 @@
|
||||
"es6-object-assign": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
|
||||
"integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
|
||||
"integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
@@ -657,6 +661,7 @@
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/shx/-/shx-0.2.2.tgz",
|
||||
"integrity": "sha1-CjBNAgsO3xMGrYFXDoDwNG31ijk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-object-assign": "1.1.0",
|
||||
"minimist": "1.2.0",
|
||||
@@ -787,7 +792,8 @@
|
||||
"typescript": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
|
||||
"integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q="
|
||||
"integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=",
|
||||
"dev": true
|
||||
},
|
||||
"unbzip2-stream": {
|
||||
"version": "1.2.5",
|
||||
|
||||
12
tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es5"
|
||||
}
|
||||
}
|
||||