Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e621a2818 | ||
|
|
247ec4c1b2 | ||
|
|
edcff069fd | ||
|
|
8afdeac306 | ||
|
|
425f861451 | ||
|
|
5a843ed02c | ||
|
|
f3bd83af03 | ||
|
|
0b3fca63b7 | ||
|
|
cbd4460df0 | ||
|
|
b941bd9a75 | ||
|
|
439b84affc | ||
|
|
66d5302e6f | ||
|
|
9e2e2b9c5c | ||
|
|
aa243ac7b0 | ||
|
|
eb421e0681 | ||
|
|
63aae8f578 | ||
|
|
e577454a31 | ||
|
|
e802bb0052 | ||
|
|
b98e5df20a | ||
|
|
7332105edb | ||
|
|
6a4feaf18d | ||
|
|
ee637d7958 | ||
|
|
8d161ce8ff | ||
|
|
8010bd8195 | ||
|
|
059f1d5505 | ||
|
|
123cab5724 | ||
|
|
c16365a0e5 | ||
|
|
a21d278c0c | ||
|
|
0466916be1 | ||
|
|
9a845d8f6a | ||
|
|
9ae1673499 | ||
|
|
2d5a5e7aef | ||
|
|
3e4d439852 |
31
CHANGELOG.md
@@ -6,6 +6,37 @@ 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.11] - 2018-10-03
|
||||
|
||||
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
|
||||
|
||||
- Add backspace and caps lock icons which avoids the overlap of their old texts.
|
||||
- Fix right and middle mouse click macro actions which were exchanged.
|
||||
- Include Agent version to the firmware update log.
|
||||
|
||||
## [1.2.10] - 2018-09-24
|
||||
|
||||
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
|
||||
|
||||
- Add History Back and History Forward scancodes.
|
||||
- Save the actual decelerated scroll speed instead of using the accelerated scroll speed by accident.
|
||||
- Allow layer switcher secondary roles only on the base layer.
|
||||
- When remapping modifiers, display a warning suggesting to remap them on all layers.
|
||||
- Display more exact instructions on the permission setup screen.
|
||||
- Set the decelerated scroll speed of the default configuration from 20 to 10.
|
||||
- Map Caps Lock without Ctrl on default keymaps.
|
||||
- Rename "Scroll Lock" to "ScrLk" and "Num Lock" to "NumLk" on keys to avoid text overlap.
|
||||
- In the scancode select2, display "Print Screen SysRq" and add SysRq above PrtScn when rendering the key.
|
||||
- Fix left and right direction titles for mouse movement macro actions.
|
||||
|
||||
## [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
|
||||
|
||||
1
ISSUE_TEMPLATE
Normal file
@@ -0,0 +1 @@
|
||||
If you're using Karabiner Elements on your Mac, then stop here! Make sure to close Karabiner Elements, then try to reproduce the issue again, even if you think that Karabiner Elements shouldn't be the cause. Karabiner Elements is the source of numerous problems, and we don't want to receive any more reports it causes.
|
||||
7051
package-lock.json
generated
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"author": "Ultimate Gadget Laboratories",
|
||||
"main": "electron/dist/electron-main.js",
|
||||
"version": "1.2.8",
|
||||
"version": "1.2.11",
|
||||
"firmwareVersion": "8.2.5",
|
||||
"deviceProtocolVersion": "4.4.0",
|
||||
"userConfigVersion": "4.0.1",
|
||||
@@ -15,8 +15,8 @@
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"engines": {
|
||||
"node": ">=8.9.1 <9.0.0",
|
||||
"npm": ">=5.6.0 <6.0.0"
|
||||
"node": ">=8.12.0 <9.0.0",
|
||||
"npm": ">=6.4.0 <7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/electron-devtools-installer": "2.0.2",
|
||||
@@ -67,7 +67,7 @@
|
||||
"rimraf": "2.6.1",
|
||||
"standard-version": "4.2.0",
|
||||
"stylelint": "9.5.0",
|
||||
"svg-sprite": "1.4.0",
|
||||
"svg-sprite": "1.5.0",
|
||||
"ts-loader": "2.3.1",
|
||||
"ts-node": "7.0.1",
|
||||
"tslint": "5.9.1",
|
||||
|
||||
244
packages/uhk-agent/package-lock.json
generated
@@ -9,7 +9,8 @@ import {
|
||||
IpcResponse,
|
||||
LogService,
|
||||
mapObjectToUserConfigBinaryBuffer,
|
||||
SaveUserConfigurationData
|
||||
SaveUserConfigurationData,
|
||||
UpdateFirmwareData
|
||||
} from 'uhk-common';
|
||||
import { deviceConnectionStateComparer, snooze, UhkHidDevice, UhkOperations } from 'uhk-usb';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
@@ -157,10 +158,12 @@ export class DeviceService {
|
||||
|
||||
public async updateFirmware(event: Electron.Event, args?: Array<string>): Promise<void> {
|
||||
const response = new FirmwareUpgradeIpcResponse();
|
||||
const data: UpdateFirmwareData = JSON.parse(args[0]);
|
||||
|
||||
let firmwarePathData: TmpFirmware;
|
||||
|
||||
try {
|
||||
this.logService.debug('Agent version:', data.versionInformation.version);
|
||||
const hardwareModules = await this.getHardwareModules(false);
|
||||
this.logService.debug('Device right firmware version:', hardwareModules.rightModuleInfo.firmwareVersion);
|
||||
this.logService.debug('Device left firmware version:', hardwareModules.leftModuleInfo.firmwareVersion);
|
||||
@@ -168,8 +171,8 @@ export class DeviceService {
|
||||
this.device.resetDeviceCache();
|
||||
this.stopPollTimer();
|
||||
|
||||
if (args && args.length > 0) {
|
||||
firmwarePathData = await saveTmpFirmware(args[0]);
|
||||
if (data.firmware) {
|
||||
firmwarePathData = await saveTmpFirmware(data.firmware);
|
||||
|
||||
const packageJson = await getPackageJsonFromPathAsync(firmwarePathData.packageJsonPath);
|
||||
this.logService.debug('New firmware version:', packageJson.firmwareVersion);
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as decompressTarbz from 'decompress-tarbz2';
|
||||
|
||||
import { TmpFirmware } from '../models/tmp-firmware';
|
||||
|
||||
export async function saveTmpFirmware(data: string): Promise<TmpFirmware> {
|
||||
export async function saveTmpFirmware(data: Array<number>): Promise<TmpFirmware> {
|
||||
const tmpDirectory = dirSync();
|
||||
const zipFilePath = path.join(tmpDirectory.name, 'firmware.bz2');
|
||||
|
||||
@@ -21,10 +21,9 @@ export async function saveTmpFirmware(data: string): Promise<TmpFirmware> {
|
||||
};
|
||||
}
|
||||
|
||||
function writeDataToFile(data: string, filePath: string): Promise<void> {
|
||||
function writeDataToFile(data: Array<number>, filePath: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const array: Array<number> = JSON.parse(data);
|
||||
const buffer = new Buffer(array);
|
||||
const buffer = new Buffer(data);
|
||||
|
||||
fs.writeFile(filePath, buffer, err => {
|
||||
if (err) {
|
||||
|
||||
@@ -3,9 +3,9 @@ import { UhkBuffer } from '../../uhk-buffer';
|
||||
import { MacroAction, MacroActionId, MacroMouseSubAction, macroActionType } from './macro-action';
|
||||
|
||||
export enum MouseButtons {
|
||||
Left = 1 << 0,
|
||||
Middle = 1 << 1,
|
||||
Right = 1 << 2
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
Middle = 2
|
||||
}
|
||||
|
||||
export interface JsObjectMouseButtonMacroAction {
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
},
|
||||
{
|
||||
"id": "70",
|
||||
"text": "Print Screen"
|
||||
"text": "Print Screen SysRq"
|
||||
},
|
||||
{
|
||||
"id": "72",
|
||||
@@ -509,6 +509,22 @@
|
||||
"type": "media",
|
||||
"scancode": 138
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "145",
|
||||
"text": "History Back",
|
||||
"additional": {
|
||||
"type": "media",
|
||||
"scancode": 548
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "146",
|
||||
"text": "History Forward",
|
||||
"additional": {
|
||||
"type": "media",
|
||||
"scancode": 549
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { assertUInt8, assertUInt16 } from '../assert';
|
||||
import { assertUInt16, assertUInt8 } from '../assert';
|
||||
import { UhkBuffer } from '../uhk-buffer';
|
||||
import { Keymap } from './keymap';
|
||||
import { Macro } from './macro';
|
||||
import { ModuleConfiguration } from './module-configuration';
|
||||
import { ConfigSerializer } from '../config-serializer';
|
||||
import { KeystrokeAction } from './key-action';
|
||||
import { SecondaryRoleAction } from './secondary-role-action';
|
||||
|
||||
export class UserConfiguration {
|
||||
|
||||
@@ -90,7 +92,7 @@ export class UserConfiguration {
|
||||
this.mouseMoveAcceleratedSpeed = jsonObject.mouseMoveAcceleratedSpeed;
|
||||
this.mouseScrollInitialSpeed = jsonObject.mouseScrollInitialSpeed;
|
||||
this.mouseScrollAcceleration = jsonObject.mouseScrollAcceleration;
|
||||
this.mouseScrollDeceleratedSpeed = jsonObject.mouseScrollAcceleration;
|
||||
this.mouseScrollDeceleratedSpeed = jsonObject.mouseScrollDeceleratedSpeed;
|
||||
this.mouseScrollBaseSpeed = jsonObject.mouseScrollBaseSpeed;
|
||||
this.mouseScrollAcceleratedSpeed = jsonObject.mouseScrollAcceleratedSpeed;
|
||||
this.moduleConfigurations = jsonObject.moduleConfigurations.map((moduleConfiguration: any) => {
|
||||
@@ -102,7 +104,9 @@ export class UserConfiguration {
|
||||
return macro;
|
||||
});
|
||||
this.keymaps = jsonObject.keymaps.map((keymap: any) => new Keymap().fromJsonObject(keymap, this.macros));
|
||||
this.clean();
|
||||
this.recalculateConfigurationLength();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -138,6 +142,8 @@ export class UserConfiguration {
|
||||
this.keymaps = buffer.readArray<Keymap>(uhkBuffer => new Keymap().fromBinary(uhkBuffer, this.macros));
|
||||
ConfigSerializer.resolveSwitchKeymapActions(this.keymaps);
|
||||
|
||||
this.clean();
|
||||
|
||||
if (this.userConfigurationLength === 0) {
|
||||
this.recalculateConfigurationLength();
|
||||
}
|
||||
@@ -222,4 +228,30 @@ export class UserConfiguration {
|
||||
this.deviceName = 'My UHK';
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove not allowed settings/bugs
|
||||
* 1. Layer Switcher secondary roles allowed only on base layers
|
||||
*/
|
||||
private clean(): void {
|
||||
for (const keymap of this.keymaps) {
|
||||
for (let layerId = 1; layerId < keymap.layers.length; layerId++) {
|
||||
const layer = keymap.layers[layerId];
|
||||
|
||||
for (const module of layer.modules) {
|
||||
for (let keyActionId = 0; keyActionId < module.keyActions.length; keyActionId++) {
|
||||
const keyAction = module.keyActions[keyActionId];
|
||||
if (!keyAction || !(keyAction instanceof KeystrokeAction)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyAction.secondaryRoleAction === SecondaryRoleAction.fn ||
|
||||
keyAction.secondaryRoleAction === SecondaryRoleAction.mod ||
|
||||
keyAction.secondaryRoleAction === SecondaryRoleAction.mouse) {
|
||||
(keyAction as any)._secondaryRoleAction = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ export * from './device-connection-state';
|
||||
export * from './hardware-modules';
|
||||
export * from './hardware-module-info';
|
||||
export * from './save-user-configuration-data';
|
||||
export * from './update-firmware-data';
|
||||
|
||||
6
packages/uhk-common/src/models/update-firmware-data.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { VersionInformation } from './version-information';
|
||||
|
||||
export interface UpdateFirmwareData {
|
||||
versionInformation: VersionInformation;
|
||||
firmware?: Array<number>;
|
||||
}
|
||||
142
packages/uhk-usb/package-lock.json
generated
@@ -25,8 +25,8 @@
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
|
||||
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
||||
"requires": {
|
||||
"delegates": "1.0.0",
|
||||
"readable-stream": "2.3.6"
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"bindings": {
|
||||
@@ -39,8 +39,8 @@
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
||||
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
|
||||
"requires": {
|
||||
"readable-stream": "2.3.6",
|
||||
"safe-buffer": "5.1.1"
|
||||
"readable-stream": "^2.3.5",
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
@@ -68,7 +68,7 @@
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
|
||||
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
|
||||
"requires": {
|
||||
"mimic-response": "1.0.0"
|
||||
"mimic-response": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"deep-extend": {
|
||||
@@ -91,7 +91,7 @@
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"requires": {
|
||||
"once": "1.4.0"
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"expand-template": {
|
||||
@@ -104,14 +104,14 @@
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"requires": {
|
||||
"aproba": "1.2.0",
|
||||
"console-control-strings": "1.1.0",
|
||||
"has-unicode": "2.0.1",
|
||||
"object-assign": "4.1.1",
|
||||
"signal-exit": "3.0.2",
|
||||
"string-width": "1.0.2",
|
||||
"strip-ansi": "3.0.1",
|
||||
"wide-align": "1.1.2"
|
||||
"aproba": "^1.0.3",
|
||||
"console-control-strings": "^1.0.0",
|
||||
"has-unicode": "^2.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wide-align": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"github-from-package": {
|
||||
@@ -139,7 +139,7 @@
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"requires": {
|
||||
"number-is-nan": "1.0.1"
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
@@ -182,7 +182,7 @@
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.3.0.tgz",
|
||||
"integrity": "sha512-zwm6vU3SsVgw3e9fu48JBaRBCJGIvAgysDsqtf5+vEexFE71bEOtaMWb5zr/zODZNzTPtQlqUUpC79k68Hspow==",
|
||||
"requires": {
|
||||
"semver": "5.5.0"
|
||||
"semver": "^5.4.1"
|
||||
}
|
||||
},
|
||||
"node-hid": {
|
||||
@@ -190,9 +190,9 @@
|
||||
"resolved": "https://registry.npmjs.org/node-hid/-/node-hid-0.5.7.tgz",
|
||||
"integrity": "sha512-dwwpOetL2+MGYgivbO22ML+45ieCGbueWv1rYxRgBoEc2QMp6UF6ZucEkYts1IA3YPWJNkmpGh6dqQ85n19szw==",
|
||||
"requires": {
|
||||
"bindings": "1.3.0",
|
||||
"nan": "2.10.0",
|
||||
"prebuild-install": "2.5.1"
|
||||
"bindings": "^1.3.0",
|
||||
"nan": "^2.6.2",
|
||||
"prebuild-install": "^2.2.2"
|
||||
}
|
||||
},
|
||||
"noop-logger": {
|
||||
@@ -205,10 +205,10 @@
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"requires": {
|
||||
"are-we-there-yet": "1.1.4",
|
||||
"console-control-strings": "1.1.0",
|
||||
"gauge": "2.7.4",
|
||||
"set-blocking": "2.0.0"
|
||||
"are-we-there-yet": "~1.1.2",
|
||||
"console-control-strings": "~1.1.0",
|
||||
"gauge": "~2.7.3",
|
||||
"set-blocking": "~2.0.0"
|
||||
}
|
||||
},
|
||||
"number-is-nan": {
|
||||
@@ -226,7 +226,7 @@
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1.0.2"
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"os-homedir": {
|
||||
@@ -239,21 +239,21 @@
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.1.tgz",
|
||||
"integrity": "sha512-3DX9L6pzwc1m1ksMkW3Ky2WLgPQUBiySOfXVl3WZyAeJSyJb4wtoH9OmeRGcubAWsMlLiL8BTHbwfm/jPQE9Ag==",
|
||||
"requires": {
|
||||
"detect-libc": "1.0.3",
|
||||
"expand-template": "1.1.0",
|
||||
"detect-libc": "^1.0.3",
|
||||
"expand-template": "^1.0.2",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "1.2.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"node-abi": "2.3.0",
|
||||
"noop-logger": "0.1.1",
|
||||
"npmlog": "4.1.2",
|
||||
"os-homedir": "1.0.2",
|
||||
"pump": "2.0.1",
|
||||
"rc": "1.2.6",
|
||||
"simple-get": "2.7.0",
|
||||
"tar-fs": "1.16.0",
|
||||
"tunnel-agent": "0.6.0",
|
||||
"which-pm-runs": "1.0.0"
|
||||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"node-abi": "^2.2.0",
|
||||
"noop-logger": "^0.1.1",
|
||||
"npmlog": "^4.0.1",
|
||||
"os-homedir": "^1.0.1",
|
||||
"pump": "^2.0.1",
|
||||
"rc": "^1.1.6",
|
||||
"simple-get": "^2.7.0",
|
||||
"tar-fs": "^1.13.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"which-pm-runs": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
@@ -266,8 +266,8 @@
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
|
||||
"integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.1",
|
||||
"once": "1.4.0"
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"rc": {
|
||||
@@ -275,10 +275,10 @@
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz",
|
||||
"integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=",
|
||||
"requires": {
|
||||
"deep-extend": "0.4.2",
|
||||
"ini": "1.3.5",
|
||||
"minimist": "1.2.0",
|
||||
"strip-json-comments": "2.0.1"
|
||||
"deep-extend": "~0.4.0",
|
||||
"ini": "~1.3.0",
|
||||
"minimist": "^1.2.0",
|
||||
"strip-json-comments": "~2.0.1"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
@@ -286,13 +286,13 @@
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "1.0.0",
|
||||
"process-nextick-args": "2.0.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
"string_decoder": "1.1.1",
|
||||
"util-deprecate": "1.0.2"
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
@@ -325,9 +325,9 @@
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
|
||||
"integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
|
||||
"requires": {
|
||||
"decompress-response": "3.3.0",
|
||||
"once": "1.4.0",
|
||||
"simple-concat": "1.0.0"
|
||||
"decompress-response": "^3.3.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
@@ -335,9 +335,9 @@
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"requires": {
|
||||
"code-point-at": "1.1.0",
|
||||
"is-fullwidth-code-point": "1.0.0",
|
||||
"strip-ansi": "3.0.1"
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
@@ -345,7 +345,7 @@
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
@@ -353,7 +353,7 @@
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "2.1.1"
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
@@ -366,10 +366,10 @@
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz",
|
||||
"integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==",
|
||||
"requires": {
|
||||
"chownr": "1.0.1",
|
||||
"mkdirp": "0.5.1",
|
||||
"pump": "1.0.3",
|
||||
"tar-stream": "1.5.5"
|
||||
"chownr": "^1.0.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"pump": "^1.0.0",
|
||||
"tar-stream": "^1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"pump": {
|
||||
@@ -377,8 +377,8 @@
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
|
||||
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.1",
|
||||
"once": "1.4.0"
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,10 +388,10 @@
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz",
|
||||
"integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
|
||||
"requires": {
|
||||
"bl": "1.2.2",
|
||||
"end-of-stream": "1.4.1",
|
||||
"readable-stream": "2.3.6",
|
||||
"xtend": "4.0.1"
|
||||
"bl": "^1.0.0",
|
||||
"end-of-stream": "^1.0.0",
|
||||
"readable-stream": "^2.0.0",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
@@ -399,7 +399,7 @@
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
@@ -417,7 +417,7 @@
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
|
||||
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
|
||||
"requires": {
|
||||
"string-width": "1.0.2"
|
||||
"string-width": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
|
||||
1
packages/uhk-web/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
out-tsc/
|
||||
4562
packages/uhk-web/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
<div class="row">
|
||||
<h1 class="col-xs-12 pane-title">
|
||||
<i class="uhk-icon uhk-icon-agent-icon"></i>
|
||||
<i class="uhk-icon uhk-icon-pure-agent-icon"></i>
|
||||
<span>About</span>
|
||||
</h1>
|
||||
<div class="col-xs-12">
|
||||
|
||||
@@ -43,4 +43,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -93,10 +93,17 @@
|
||||
<h4 *ngIf="activeTab === TabName.Hold">Hold mouse button</h4>
|
||||
<h4 *ngIf="activeTab === TabName.Release">Release mouse button</h4>
|
||||
<div class="btn-group">
|
||||
<button *ngFor="let buttonLabel of buttonLabels; let buttonIndex = index"
|
||||
class="btn btn-default"
|
||||
[class.btn-primary]="hasButton(buttonIndex)"
|
||||
(click)="setMouseClick(buttonIndex)">{{buttonLabel}}
|
||||
<button class="btn btn-default"
|
||||
[class.btn-primary]="hasButton(MouseButtons.Left)"
|
||||
(click)="setMouseClick(MouseButtons.Left)">Left
|
||||
</button>
|
||||
<button class="btn btn-default"
|
||||
[class.btn-primary]="hasButton(MouseButtons.Middle)"
|
||||
(click)="setMouseClick(MouseButtons.Middle)">Middle
|
||||
</button>
|
||||
<button class="btn btn-default"
|
||||
[class.btn-primary]="hasButton(MouseButtons.Right)"
|
||||
(click)="setMouseClick(MouseButtons.Right)">Right
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||
|
||||
import {
|
||||
MacroMouseSubAction,
|
||||
MouseButtons,
|
||||
MouseButtonMacroAction,
|
||||
MoveMouseMacroAction,
|
||||
ScrollMouseMacroAction,
|
||||
MacroMouseSubAction
|
||||
ScrollMouseMacroAction
|
||||
} from 'uhk-common';
|
||||
import { Tab } from '../../../../popover/tab';
|
||||
import { MacroBaseComponent } from '../macro-base.component';
|
||||
@@ -33,6 +34,7 @@ export class MacroMouseTabComponent extends MacroBaseComponent implements OnInit
|
||||
@ViewChild('tab') selectedTab: Tab;
|
||||
|
||||
/* tslint:disable:variable-name: It is an enum type. So it can start with uppercase. */
|
||||
MouseButtons = MouseButtons;
|
||||
TabName = TabName;
|
||||
/* tslint:enable:variable-name */
|
||||
activeTab: TabName;
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
KeyMacroAction,
|
||||
KeyModifiers,
|
||||
MacroAction,
|
||||
MouseButtons,
|
||||
MouseButtonMacroAction,
|
||||
MoveMouseMacroAction,
|
||||
ScrollMouseMacroAction,
|
||||
@@ -176,7 +177,7 @@ export class MacroItemComponent implements OnInit, OnChanges {
|
||||
|
||||
let needAnd: boolean;
|
||||
if (Math.abs(typedAction.x) !== 0) {
|
||||
this.title += ` by ${Math.abs(typedAction.x)}px ${typedAction.x > 0 ? 'leftward' : 'rightward'}`;
|
||||
this.title += ` by ${Math.abs(typedAction.x)}px ${typedAction.x > 0 ? 'rightward' : 'leftward'}`;
|
||||
needAnd = true;
|
||||
}
|
||||
if (Math.abs(typedAction.y) !== 0) {
|
||||
@@ -197,12 +198,11 @@ export class MacroItemComponent implements OnInit, OnChanges {
|
||||
this.title = 'Release mouse button: ';
|
||||
}
|
||||
|
||||
const buttonLabels: string[] = ['Left', 'Middle', 'Right'];
|
||||
const selectedButtons: boolean[] = action.getMouseButtons();
|
||||
const selectedButtonLabels: string[] = [];
|
||||
selectedButtons.forEach((isSelected, idx) => {
|
||||
if (isSelected && buttonLabels[idx]) {
|
||||
selectedButtonLabels.push(buttonLabels[idx]);
|
||||
if (isSelected && MouseButtons[idx]) {
|
||||
selectedButtonLabels.push(MouseButtons[idx]);
|
||||
}
|
||||
});
|
||||
this.title += selectedButtonLabels.join(', ');
|
||||
|
||||
@@ -47,10 +47,14 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div [ngSwitch]="activeTab">
|
||||
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content"
|
||||
[defaultKeyAction]="defaultKeyAction"
|
||||
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content pr-10"
|
||||
[defaultKeyAction]="shadowKeyAction"
|
||||
[secondaryRoleEnabled]="true"
|
||||
[allowRemapOnAllKeymapWarning]="true"
|
||||
[remapInfo]="remapInfo"
|
||||
[showLayerSwitcherInSecondaryRoles]="currentLayer === 0"
|
||||
(validAction)="keyActionValid=$event"
|
||||
(keyActionChange)="keystrokeActionChange($event)"
|
||||
></keypress-tab>
|
||||
<layer-tab #tab *ngSwitchCase="tabName.Layer" class="popover-content"
|
||||
[defaultKeyAction]="defaultKeyAction"
|
||||
@@ -85,10 +89,12 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<label [ngClass]="{ disabled: disableRemapOnAllLayer }">
|
||||
<input type="checkbox"
|
||||
name="remapOnAllLayer"
|
||||
[(ngModel)]="remapInfo.remapOnAllLayer"> Remap on all layers
|
||||
[(ngModel)]="remapInfo.remapOnAllLayer"
|
||||
[disabled]="disableRemapOnAllLayer"
|
||||
(ngModelChange)="remapInfoChange()"> 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%;
|
||||
@@ -121,5 +125,10 @@
|
||||
|
||||
label {
|
||||
margin-right: 5px;
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
color: #959595;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
KeystrokeAction,
|
||||
MouseAction,
|
||||
PlayMacroAction,
|
||||
SecondaryRoleAction,
|
||||
SwitchKeymapAction,
|
||||
SwitchLayerAction
|
||||
} from 'uhk-common';
|
||||
@@ -104,10 +106,13 @@ export class PopoverComponent implements OnChanges {
|
||||
topPosition: number = 0;
|
||||
leftPosition: number = 0;
|
||||
animationState: string;
|
||||
shadowKeyAction: KeyAction;
|
||||
disableRemapOnAllLayer = false;
|
||||
|
||||
private readonly currentKeymap$ = new BehaviorSubject<Keymap>(undefined);
|
||||
|
||||
constructor(store: Store<AppState>) {
|
||||
constructor(private store: Store<AppState>,
|
||||
private cdRef: ChangeDetectorRef) {
|
||||
this.animationState = 'closed';
|
||||
this.keymaps$ = store.let(getKeymaps())
|
||||
.combineLatest(this.currentKeymap$)
|
||||
@@ -123,8 +128,10 @@ export class PopoverComponent implements OnChanges {
|
||||
|
||||
if (change['defaultKeyAction']) {
|
||||
let tab: TabName;
|
||||
this.disableRemapOnAllLayer = false;
|
||||
|
||||
if (this.defaultKeyAction instanceof KeystrokeAction) {
|
||||
this.keystrokeActionChange(this.defaultKeyAction);
|
||||
tab = TabName.Keypress;
|
||||
} else if (this.defaultKeyAction instanceof SwitchLayerAction) {
|
||||
tab = TabName.Layer;
|
||||
@@ -188,12 +195,39 @@ export class PopoverComponent implements OnChanges {
|
||||
|
||||
selectTab(tab: TabName): void {
|
||||
this.activeTab = tab;
|
||||
if (tab === TabName.Keypress) {
|
||||
this.keystrokeActionChange(this.defaultKeyAction as KeystrokeAction);
|
||||
}
|
||||
}
|
||||
|
||||
onOverlay() {
|
||||
this.cancel.emit(undefined);
|
||||
}
|
||||
|
||||
remapInfoChange(): void {
|
||||
this.selectedTab.remapInfoChanged(this.remapInfo);
|
||||
}
|
||||
|
||||
keystrokeActionChange(keystrokeAction: KeystrokeAction): void {
|
||||
this.shadowKeyAction = keystrokeAction;
|
||||
const disableRemapOnAllLayer =
|
||||
keystrokeAction &&
|
||||
this.currentLayer === 0 &&
|
||||
(keystrokeAction.secondaryRoleAction === SecondaryRoleAction.fn ||
|
||||
keystrokeAction.secondaryRoleAction === SecondaryRoleAction.mod ||
|
||||
keystrokeAction.secondaryRoleAction === SecondaryRoleAction.mouse);
|
||||
|
||||
if (this.disableRemapOnAllLayer !== disableRemapOnAllLayer) {
|
||||
this.disableRemapOnAllLayer = disableRemapOnAllLayer;
|
||||
|
||||
if (disableRemapOnAllLayer) {
|
||||
this.remapInfo.remapOnAllLayer = false;
|
||||
}
|
||||
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
}
|
||||
|
||||
private calculatePosition() {
|
||||
const offsetLeft: number = this.wrapPosition.left + 265; // 265 is a width of the side menu with a margin
|
||||
const popover: HTMLElement = this.popoverHost.nativeElement;
|
||||
|
||||
@@ -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>
|
||||
@@ -92,6 +92,11 @@
|
||||
data-placement="bottom"></icon>
|
||||
</div>
|
||||
|
||||
<div *ngIf="warningVisible" class="alert alert-warning remap-warning" role="alert">
|
||||
You're about to remap a modifier key only on this layer. You probably want to remap it on all layers. If so, check
|
||||
the <strong>Remap on all layers</strong> checkbox below.
|
||||
</div>
|
||||
|
||||
<div class="disabled-state--text">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
When a key is configured as layer switcher key, you can't assign other functions to it.
|
||||
|
||||
@@ -89,4 +89,11 @@
|
||||
display: inline-block;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.remap-warning {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 0;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,31 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
SimpleChanges
|
||||
} from '@angular/core';
|
||||
import { KeyAction, KeystrokeAction, KeystrokeType, SCANCODES, SECONDARY_ROLES } from 'uhk-common';
|
||||
|
||||
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';
|
||||
import { RemapInfo } from '../../../../models/remap-info';
|
||||
|
||||
export const secondaryRoleFilter = (showLayerSwitchers: boolean) => {
|
||||
return (data): boolean => {
|
||||
if (showLayerSwitchers) {
|
||||
return data;
|
||||
}
|
||||
|
||||
return data.text !== 'Layer switcher';
|
||||
};
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'keypress-tab',
|
||||
@@ -14,38 +36,43 @@ import { SelectOptionData } from '../../../../models/select-option-data';
|
||||
export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
@Input() defaultKeyAction: KeyAction;
|
||||
@Input() secondaryRoleEnabled: boolean;
|
||||
@Input() allowRemapOnAllKeymapWarning: boolean;
|
||||
@Input() remapInfo: RemapInfo;
|
||||
@Input() showLayerSwitcherInSecondaryRoles: boolean;
|
||||
|
||||
leftModifiers: string[];
|
||||
rightModifiers: string[];
|
||||
@Output() keyActionChange = new EventEmitter<KeystrokeAction>();
|
||||
|
||||
leftModifierSelects: boolean[];
|
||||
rightModifierSelects: boolean[];
|
||||
leftModifiers: KeyModifierModel[];
|
||||
rightModifiers: KeyModifierModel[];
|
||||
|
||||
scanCodeGroups: Array<SelectOptionData>;
|
||||
secondaryRoleGroups: Array<SelectOptionData>;
|
||||
secondaryRoleGroups: Array<SelectOptionData> = [];
|
||||
|
||||
selectedScancodeOption: SelectOptionData;
|
||||
selectedSecondaryRoleIndex: number;
|
||||
warningVisible: boolean;
|
||||
|
||||
constructor(private mapper: MapperService) {
|
||||
constructor(private mapper: MapperService,
|
||||
private cdRef: ChangeDetectorRef) {
|
||||
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;
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.showLayerSwitcherInSecondaryRoles) {
|
||||
this.fillSecondaryRoles();
|
||||
}
|
||||
this.fromKeyAction(this.defaultKeyAction);
|
||||
this.validAction.emit(this.keyActionValid());
|
||||
this.keyActionChanged(false);
|
||||
}
|
||||
|
||||
keyActionValid(keystrokeAction?: KeystrokeAction): boolean {
|
||||
@@ -56,16 +83,16 @@ 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.validAction.emit(this.keyActionValid());
|
||||
this.leftModifiers = event.left;
|
||||
this.rightModifiers = event.right;
|
||||
this.keyActionChanged();
|
||||
}
|
||||
|
||||
fromKeyAction(keyAction: KeyAction): boolean {
|
||||
@@ -76,16 +103,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 +130,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,21 +141,31 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
toggleModifier(right: boolean, index: number) {
|
||||
const modifierSelects: boolean[] = right ? this.rightModifierSelects : this.leftModifierSelects;
|
||||
modifierSelects[index] = !modifierSelects[index];
|
||||
|
||||
this.validAction.emit(this.keyActionValid());
|
||||
toggleModifier(modifier: KeyModifierModel): void {
|
||||
modifier.checked = !modifier.checked;
|
||||
this.keyActionChanged();
|
||||
}
|
||||
|
||||
onSecondaryRoleChange(id: string) {
|
||||
this.selectedSecondaryRoleIndex = +id;
|
||||
this.keyActionChanged();
|
||||
}
|
||||
|
||||
onScancodeChange(id: string) {
|
||||
this.selectedScancodeOption = this.findScancodeOptionById(id);
|
||||
|
||||
this.validAction.emit(this.keyActionValid());
|
||||
this.keyActionChanged();
|
||||
}
|
||||
|
||||
modifiersTrackBy(index: number, modifier: KeyModifierModel): string {
|
||||
return `${modifier.value}${modifier.checked}`;
|
||||
}
|
||||
|
||||
remapInfoChanged(remapInfo: RemapInfo): void {
|
||||
this.remapInfo = remapInfo;
|
||||
const keystrokeAction = this.toKeyAction();
|
||||
this.calculateRemapOnAllLayerWarningVisibility(keystrokeAction);
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
private findScancodeOptionBy(predicate: (option: SelectOptionData) => boolean): SelectOptionData {
|
||||
@@ -196,4 +225,27 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
||||
return [scanCode, type];
|
||||
}
|
||||
|
||||
private keyActionChanged(dispatch = true): void {
|
||||
const keystrokeAction = this.toKeyAction();
|
||||
this.validAction.emit(this.keyActionValid(keystrokeAction));
|
||||
this.calculateRemapOnAllLayerWarningVisibility(keystrokeAction);
|
||||
|
||||
if (dispatch) {
|
||||
this.keyActionChange.emit(keystrokeAction);
|
||||
}
|
||||
}
|
||||
|
||||
private calculateRemapOnAllLayerWarningVisibility(keystrokeAction: KeystrokeAction): void {
|
||||
this.warningVisible = this.allowRemapOnAllKeymapWarning &&
|
||||
this.remapInfo &&
|
||||
!this.remapInfo.remapOnAllLayer &&
|
||||
keystrokeAction &&
|
||||
!keystrokeAction.hasScancode() &&
|
||||
keystrokeAction.hasOnlyOneActiveModifier();
|
||||
}
|
||||
|
||||
private fillSecondaryRoles(): void {
|
||||
this.secondaryRoleGroups = SECONDARY_ROLES
|
||||
.filter(secondaryRoleFilter(this.showLayerSwitcherInSecondaryRoles));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { EventEmitter, Output } from '@angular/core';
|
||||
import { KeyAction } from 'uhk-common';
|
||||
|
||||
import { RemapInfo } from '../../../models/remap-info';
|
||||
|
||||
export abstract class Tab {
|
||||
@Output() validAction = new EventEmitter<boolean>();
|
||||
|
||||
abstract keyActionValid(): boolean;
|
||||
abstract fromKeyAction(keyAction: KeyAction): boolean;
|
||||
abstract toKeyAction(): KeyAction;
|
||||
remapInfoChanged(remapInfo: RemapInfo): void {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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',
|
||||
@@ -68,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,
|
||||
|
||||
@@ -21,9 +21,13 @@
|
||||
</p>
|
||||
|
||||
<div *ngIf="state.showWhatWillThisDoContent">
|
||||
Agent uses the following script to set up permissions. You can run it manually as root, then
|
||||
<a class="link-inline"
|
||||
(click)="retry()">retry</a>.
|
||||
If you want to set up permissions manually:
|
||||
<ol>
|
||||
<li>Open a terminal.</li>
|
||||
<li>Run <code>su</code> to become root.</li>
|
||||
<li>Paste the following script, and <a class="link-inline" (click)="retry()">retry</a>.</li>
|
||||
</ol>
|
||||
|
||||
<div class="copy-container">
|
||||
<span class="fa fa-2x fa-copy"
|
||||
ngxClipboard
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
</li>
|
||||
<li class="sidebar__level-0--item" [routerLinkActive]="['active']">
|
||||
<div class="sidebar__level-0">
|
||||
<i class="uhk-icon uhk-icon-agent-icon"></i> Agent
|
||||
<i class="uhk-icon uhk-icon-pure-agent-icon"></i> Agent
|
||||
<i class="fa fa-chevron-up pull-right"
|
||||
(click)="toggleHide($event, 'agent')"></i>
|
||||
</div>
|
||||
|
||||
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,13 +120,13 @@ 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;
|
||||
@@ -140,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,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: {
|
||||
@@ -265,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;
|
||||
@@ -293,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;
|
||||
};
|
||||
@@ -49,6 +49,7 @@ import {
|
||||
SvgKeyHoverEvent
|
||||
} from '../../../models/svg-key-events';
|
||||
import { RemapInfo } from '../../../models/remap-info';
|
||||
import { mapLeftRigthModifierToKeyActionModifier } from '../../../util';
|
||||
|
||||
interface NameValuePair {
|
||||
name: string;
|
||||
@@ -181,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
|
||||
}
|
||||
@@ -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,7 +1,14 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Action, Store } from '@ngrx/store';
|
||||
|
||||
import { DeviceConnectionState, IpcEvents, IpcResponse, LogService, SaveUserConfigurationData } from 'uhk-common';
|
||||
import {
|
||||
DeviceConnectionState,
|
||||
IpcEvents,
|
||||
IpcResponse,
|
||||
LogService,
|
||||
SaveUserConfigurationData,
|
||||
UpdateFirmwareData
|
||||
} from 'uhk-common';
|
||||
import { AppState } from '../store';
|
||||
import { IpcCommonRenderer } from './ipc-common-renderer';
|
||||
import {
|
||||
@@ -34,12 +41,8 @@ export class DeviceRendererService {
|
||||
this.ipcRenderer.send(IpcEvents.device.loadConfigurations);
|
||||
}
|
||||
|
||||
updateFirmware(data?: Array<number>): void {
|
||||
if (data) {
|
||||
this.ipcRenderer.send(IpcEvents.device.updateFirmware, JSON.stringify(data));
|
||||
} else {
|
||||
this.ipcRenderer.send(IpcEvents.device.updateFirmware);
|
||||
}
|
||||
updateFirmware(data: UpdateFirmwareData): void {
|
||||
this.ipcRenderer.send(IpcEvents.device.updateFirmware, JSON.stringify(data));
|
||||
}
|
||||
|
||||
startConnectionPoller(): void {
|
||||
|
||||
@@ -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']);
|
||||
@@ -159,8 +261,8 @@ export class MapperService {
|
||||
this.basicScanCodeTextMap.set(67, ['F10']);
|
||||
this.basicScanCodeTextMap.set(68, ['F11']);
|
||||
this.basicScanCodeTextMap.set(69, ['F12']);
|
||||
this.basicScanCodeTextMap.set(70, ['PrtScn']);
|
||||
this.basicScanCodeTextMap.set(71, ['Scroll Lock']);
|
||||
this.basicScanCodeTextMap.set(70, ['PrtScn', 'SysRq']);
|
||||
this.basicScanCodeTextMap.set(71, ['ScrLk']);
|
||||
this.basicScanCodeTextMap.set(72, ['Pause']);
|
||||
this.basicScanCodeTextMap.set(73, ['Insert']);
|
||||
this.basicScanCodeTextMap.set(74, ['Home']);
|
||||
@@ -172,12 +274,12 @@ export class MapperService {
|
||||
this.basicScanCodeTextMap.set(80, ['Left Arrow']);
|
||||
this.basicScanCodeTextMap.set(81, ['Down Arrow']);
|
||||
this.basicScanCodeTextMap.set(82, ['Up Arrow']);
|
||||
this.basicScanCodeTextMap.set(83, ['Num Lock']);
|
||||
this.basicScanCodeTextMap.set(83, ['NumLk']);
|
||||
this.basicScanCodeTextMap.set(84, ['/']);
|
||||
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,14 +326,19 @@ 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.mediaScanCodeTextMap.set(548, ['Hist -']);
|
||||
this.mediaScanCodeTextMap.set(549, ['Hist +']);
|
||||
|
||||
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 {
|
||||
this.basicScancodeIcons = new Map<number, string>();
|
||||
this.basicScancodeIcons.set(42, 'icon-kbd__backspace');
|
||||
this.basicScancodeIcons.set(57, 'icon-kbd__caps-lock');
|
||||
this.basicScancodeIcons.set(79, 'icon-kbd__mod--arrow-right');
|
||||
this.basicScancodeIcons.set(80, 'icon-kbd__mod--arrow-left');
|
||||
this.basicScancodeIcons.set(81, 'icon-kbd__mod--arrow-down');
|
||||
@@ -266,8 +373,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 +390,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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"mouseMoveAcceleratedSpeed": 64,
|
||||
"mouseScrollInitialSpeed": 20,
|
||||
"mouseScrollAcceleration": 20,
|
||||
"mouseScrollDeceleratedSpeed": 20,
|
||||
"mouseScrollDeceleratedSpeed": 10,
|
||||
"mouseScrollBaseSpeed": 20,
|
||||
"mouseScrollAcceleratedSpeed": 50,
|
||||
"moduleConfigurations": [],
|
||||
@@ -595,8 +595,7 @@
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"scancode": 57,
|
||||
"modifierMask": 1
|
||||
"scancode": 57
|
||||
},
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
@@ -1581,8 +1580,7 @@
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"scancode": 57,
|
||||
"modifierMask": 1
|
||||
"scancode": 57
|
||||
},
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
@@ -2576,8 +2574,7 @@
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"scancode": 57,
|
||||
"modifierMask": 1
|
||||
"scancode": 57
|
||||
},
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
@@ -3559,8 +3556,7 @@
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"scancode": 57,
|
||||
"modifierMask": 1
|
||||
"scancode": 57
|
||||
},
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
@@ -4551,8 +4547,7 @@
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"scancode": 57,
|
||||
"modifierMask": 1
|
||||
"scancode": 57
|
||||
},
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
@@ -5528,8 +5523,7 @@
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"scancode": 57,
|
||||
"modifierMask": 1
|
||||
"scancode": 57
|
||||
},
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
@@ -6513,8 +6507,7 @@
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
"type": "basic",
|
||||
"scancode": 57,
|
||||
"modifierMask": 1
|
||||
"scancode": 57
|
||||
},
|
||||
{
|
||||
"keyActionType": "keystroke",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -50,6 +50,7 @@ import {
|
||||
} from '../actions/user-config';
|
||||
import { DefaultUserConfigurationService } from '../../services/default-user-configuration.service';
|
||||
import { DataStorageRepositoryService } from '../../services/datastorage-repository.service';
|
||||
import { getVersions } from '../../util';
|
||||
|
||||
@Injectable()
|
||||
export class DeviceEffects {
|
||||
@@ -201,12 +202,17 @@ export class DeviceEffects {
|
||||
|
||||
@Effect({dispatch: false}) updateFirmware$ = this.actions$
|
||||
.ofType<UpdateFirmwareAction>(ActionTypes.UPDATE_FIRMWARE)
|
||||
.do(() => this.deviceRendererService.updateFirmware());
|
||||
.do(() => this.deviceRendererService.updateFirmware({
|
||||
versionInformation: getVersions()
|
||||
}));
|
||||
|
||||
@Effect({dispatch: false}) updateFirmwareWith$ = this.actions$
|
||||
.ofType<UpdateFirmwareWithAction>(ActionTypes.UPDATE_FIRMWARE_WITH)
|
||||
.map(action => action.payload)
|
||||
.do(data => this.deviceRendererService.updateFirmware(data));
|
||||
.do(data => this.deviceRendererService.updateFirmware({
|
||||
versionInformation: getVersions(),
|
||||
firmware: data
|
||||
}));
|
||||
|
||||
@Effect() updateFirmwareReply$ = this.actions$
|
||||
.ofType<UpdateFirmwareReplyAction>(ActionTypes.UPDATE_FIRMWARE_REPLY)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 19 KiB |
@@ -16,6 +16,10 @@ html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.uhk-icon-pure-agent-icon {
|
||||
background: url('assets/images/agent-icon.png') no-repeat;
|
||||
}
|
||||
|
||||
.uhk-icon {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
|
||||
@@ -1 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="31" height="16" viewBox="0 0 31 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><svg width="16" height="16" viewBox="0 0 16 16" id="icon-0401-usb-stick" xmlns="http://www.w3.org/2000/svg"><path d="M6.5 2a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 1 0v-1a.5.5 0 0 0-.5-.5zM8.5 2a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 1 0v-1a.5.5 0 0 0-.5-.5z"/><path d="M11.5 5H11V.5a.5.5 0 0 0-.5-.5h-6a.5.5 0 0 0-.5.5V5h-.5a.5.5 0 0 0-.5.5v9.375c1 1.5 8 1.5 9 0V5.5a.5.5 0 0 0-.5-.5zM5 13.5a.5.5 0 0 1-1 0v-6a.5.5 0 0 1 1 0v6zM10 5H5V1h5v4z"/></svg><svg width="15" height="15" viewBox="0 0 15 15" id="icon-agent-icon" x="16" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x2="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(12 0 0 -12 0 6)" id="abb"><stop offset="0" stop-color="#85878d"/><stop offset=".001" stop-color="#85878d"/><stop offset=".001" stop-color="#5d5f63"/><stop offset=".526" stop-color="#ccc"/><stop offset="1" stop-color="#5d5c62"/></linearGradient><linearGradient id="aba" gradientTransform="matrix(12 0 0 -12 0 6)" gradientUnits="userSpaceOnUse" x2="1"><stop offset="0" stop-color="#85878d"/><stop offset=".001" stop-color="#85878d"/><stop offset=".001" stop-color="#85878d"/><stop offset=".495" stop-color="#ccc"/><stop offset="1" stop-color="#5d5c62"/></linearGradient><clipPath id="abc"><path d="M2.398 12A2.393 2.393 0 0 1 0 9.602V2.398A2.393 2.393 0 0 1 2.398 0h7.203A2.394 2.394 0 0 1 12 2.398v7.204A2.394 2.394 0 0 1 9.601 12H2.398zM.602 7.199v1.199c0 .454.329.575.5.602.054.008.097 0 .097 0h3.602c.301 0 .597-.301.597-.301s.301-.301.602-.301.602.301.602.301.296.301.597.301h3.602c.597 0 .597-.602.597-.602V7.199c0-1.801-1.199-1.801-1.199-1.801h-3c-.301 0-.597.903-.597.903s-.301.898-.602.898-.602-.898-.602-.898-.296-.903-.597-.903h-3s-1.199 0-1.199 1.801"/></clipPath><linearGradient gradientUnits="userSpaceOnUse" x2="11.746" y1="11.542" x1=".915" id="abd" xlink:href="#aba"/><linearGradient y2="-.051" x2="12" y1="11.898" x1=".102" gradientUnits="userSpaceOnUse" id="abe" xlink:href="#abb"/></defs><g transform="matrix(1.25 0 0 -1.25 0 15)"><path d="M11.473 5.117H.416v4.266h11.057V5.117z" fill="#343434"/><g clip-path="url(#abc)" fill="url(#abd)"><path d="M2.398 12A2.393 2.393 0 0 1 0 9.602V2.398A2.393 2.393 0 0 1 2.398 0h7.203A2.394 2.394 0 0 1 12 2.398v7.204A2.394 2.394 0 0 1 9.601 12H2.398zM.602 7.199v1.199c0 .454.329.575.5.602.054.008.097 0 .097 0h3.602c.301 0 .597-.301.597-.301s.301-.301.602-.301.602.301.602.301.296.301.597.301h3.602c.597 0 .597-.602.597-.602V7.199c0-1.801-1.199-1.801-1.199-1.801h-3c-.301 0-.597.903-.597.903s-.301.898-.602.898-.602-.898-.602-.898-.296-.903-.597-.903h-3s-1.199 0-1.199 1.801" fill="url(#abe)"/></g></g></svg></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="31" height="16" viewBox="0 0 31 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><svg width="16" height="16" viewBox="0 0 16 16" id="icon-0401-usb-stick" xmlns="http://www.w3.org/2000/svg"><path d="M6.5 2a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 1 0v-1a.5.5 0 0 0-.5-.5zM8.5 2a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 1 0v-1a.5.5 0 0 0-.5-.5z"/><path d="M11.5 5H11V.5a.5.5 0 0 0-.5-.5h-6a.5.5 0 0 0-.5.5V5h-.5a.5.5 0 0 0-.5.5v9.375c1 1.5 8 1.5 9 0V5.5a.5.5 0 0 0-.5-.5zM5 13.5a.5.5 0 0 1-1 0v-6a.5.5 0 0 1 1 0v6zM10 5H5V1h5v4z"/></svg><svg width="15" height="15" viewBox="0 0 15 15" id="icon-agent-icon" x="16" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(12 0 0 -12 0 6)" spreadMethod="pad" id="bb"><stop offset="0" stop-color="#85878d"/><stop offset=".001" stop-color="#85878d"/><stop offset=".001" stop-color="#5d5f63"/><stop offset=".526" stop-color="#ccc"/><stop offset="1" stop-color="#5d5c62"/></linearGradient><linearGradient id="ba" spreadMethod="pad" gradientTransform="matrix(12 0 0 -12 0 6)" gradientUnits="userSpaceOnUse" y2="0" x2="1" y1="0" x1="0"><stop offset="0" stop-color="#85878d"/><stop offset=".001" stop-color="#85878d"/><stop offset=".001" stop-color="#85878d"/><stop offset=".495" stop-color="#ccc"/><stop offset="1" stop-color="#5d5c62"/></linearGradient><clipPath clipPathUnits="userSpaceOnUse" id="bc"><path d="M2.398 12A2.393 2.393 0 0 1 0 9.602V2.398A2.393 2.393 0 0 1 2.398 0h7.203A2.394 2.394 0 0 1 12 2.398v7.204A2.394 2.394 0 0 1 9.601 12H2.398zM.602 7.199v1.199c0 .454.329.575.5.602.054.008.097 0 .097 0h3.602c.301 0 .597-.301.597-.301s.301-.301.602-.301.602.301.602.301.296.301.597.301h3.602c.597 0 .597-.602.597-.602V7.199c0-1.801-1.199-1.801-1.199-1.801h-3c-.301 0-.597.903-.597.903s-.301.898-.602.898-.602-.898-.602-.898-.296-.903-.597-.903h-3s-1.199 0-1.199 1.801"/></clipPath><linearGradient gradientUnits="userSpaceOnUse" y2="0" x2="11.746" y1="11.542" x1=".915" id="bd" xlink:href="#ba"/><linearGradient y2="-.051" x2="12" y1="11.898" x1=".102" gradientUnits="userSpaceOnUse" id="be" xlink:href="#bb"/></defs><path d="M14.341 8.604H.52V3.27h13.821v5.333z" fill="#343434"/><g clip-path="url(#bc)" fill="url(#bd)" transform="matrix(1.25 0 0 -1.25 0 15)"><path d="M2.398 12A2.393 2.393 0 0 1 0 9.602V2.398A2.393 2.393 0 0 1 2.398 0h7.203A2.394 2.394 0 0 1 12 2.398v7.204A2.394 2.394 0 0 1 9.601 12H2.398zM.602 7.199v1.199c0 .454.329.575.5.602.054.008.097 0 .097 0h3.602c.301 0 .597-.301.597-.301s.301-.301.602-.301.602.301.602.301.296.301.597.301h3.602c.597 0 .597-.602.597-.602V7.199c0-1.801-1.199-1.801-1.199-1.801h-3c-.301 0-.597.903-.597.903s-.301.898-.602.898-.602-.898-.602-.898-.296-.903-.597-.903h-3s-1.199 0-1.199 1.801" fill="url(#be)"/></g></svg></svg>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.9 KiB |
@@ -8,5 +8,6 @@
|
||||
}
|
||||
|
||||
.uhk-icon-agent-icon {
|
||||
background: url('assets/images/agent-icon.png') no-repeat;
|
||||
@extend %svg-common;
|
||||
background-position: 100% 0;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 43 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M576 64H205.26A63.97 63.97 0 0 0 160 82.75L9.37 233.37c-12.5 12.5-12.5 32.76 0 45.25L160 429.25c12 12 28.28 18.75 45.25 18.75H576c35.35 0 64-28.65 64-64V128c0-35.35-28.65-64-64-64zm-84.69 254.06c6.25 6.25 6.25 16.38 0 22.63l-22.62 22.62c-6.25 6.25-16.38 6.25-22.63 0L384 301.25l-62.06 62.06c-6.25 6.25-16.38 6.25-22.63 0l-22.62-22.62c-6.25-6.25-6.25-16.38 0-22.63L338.75 256l-62.06-62.06c-6.25-6.25-6.25-16.38 0-22.63l22.62-22.62c6.25-6.25 16.38-6.25 22.63 0L384 210.75l62.06-62.06c6.25-6.25 16.38-6.25 22.63 0l22.62 22.62c6.25 6.25 6.25 16.38 0 22.63L429.25 256l62.06 62.06z"/></svg>
|
||||
<!--
|
||||
Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com
|
||||
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
-->
|
||||
|
After Width: | Height: | Size: 890 B |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<path d="M 224 0 C 140.2 0 72 68.2 72 152 L 72 224 L 48 224 C 21.5 224 0 245.5 0 272 L 0 464 C 0 490.5 21.5 512 48 512 L 400 512 C 426.5 512 448 490.5 448 464 L 448 272 C 448 245.5 426.5 224 400 224 L 376 224 L 376 152 C 376 68.2 307.8 0 224 0 z M 224 80 C 263.7 80 296 112.3 296 152 L 296 224 L 152 224 L 152 152 C 152 112.3 184.3 80 224 80 z M 211.47656 290.19141 L 236.63477 290.19141 L 299.14648 454.2168 L 276.07422 454.2168 L 261.13281 412.13867 L 187.19531 412.13867 L 172.25391 454.2168 L 148.85352 454.2168 L 211.47656 290.19141 z M 224 312.05469 L 193.89844 393.68164 L 254.21289 393.68164 L 224 312.05469 z " />
|
||||
</svg>
|
||||
<!--
|
||||
Based on Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com
|
||||
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
-->
|
||||
|
After Width: | Height: | Size: 939 B |
0
packages/uhk-web/src/svgs/keyboard/icons/kbd__media--calculator.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
packages/uhk-web/src/svgs/keyboard/icons/kbd__media--email-client.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 522 B |
0
packages/uhk-web/src/svgs/keyboard/icons/kbd__media--web-browser.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 988.74573 512.02081">
|
||||
<path d="M 49.021484 0.013671875 C 24.637109 -0.54414061 3.5527137e-15 16.517187 0 47.867188 L 0 463.96875 C 0 501.46875 40.700391 524.06758 72.400391 505.26758 L 424.40039 297.26758 C 455.80039 278.76758 455.90039 233.16797 424.40039 214.66797 L 72.400391 6.5683594 C 65.250391 2.3433594 57.149609 0.19960937 49.021484 0.013671875 z M 588.74609 33.052734 C 562.24609 33.052734 540.74609 54.552734 540.74609 81.052734 L 540.74609 433.05273 C 540.74609 459.55273 562.24609 481.05273 588.74609 481.05273 L 684.74609 481.05273 C 711.24609 481.05273 732.74609 459.55273 732.74609 433.05273 L 732.74609 81.052734 C 732.74609 54.552734 711.24609 33.052734 684.74609 33.052734 L 588.74609 33.052734 z M 844.74609 33.052734 C 818.24609 33.052734 796.74609 54.552734 796.74609 81.052734 L 796.74609 433.05273 C 796.74609 459.55273 818.24609 481.05273 844.74609 481.05273 L 940.74609 481.05273 C 967.24604 481.05273 988.74609 459.55273 988.74609 433.05273 L 988.74609 81.052734 C 988.74609 54.552734 967.24604 33.052734 940.74609 33.052734 L 844.74609 33.052734 z " />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
0
packages/uhk-web/src/svgs/keyboard/icons/kbd__system_power_down.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 716 B After Width: | Height: | Size: 716 B |
0
packages/uhk-web/src/svgs/keyboard/icons/kbd__system_wake_up.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1,176 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="31.177315mm"
|
||||
height="14.907915mm"
|
||||
viewBox="0 0 110.4708 52.823321"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="segments_dvr.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="12.310946"
|
||||
inkscape:cx="55.235392"
|
||||
inkscape:cy="26.411669"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="false"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1144"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(967.89459,-355.26718)">
|
||||
<rect
|
||||
style="opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="rect4658"
|
||||
width="110.4708"
|
||||
height="52.823322"
|
||||
x="-967.89459"
|
||||
y="355.26718"
|
||||
ry="2.2743988" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -926.64583,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9733,-0.97384 0.9734,-0.97384 0.9736,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5313,0.53114 -0.9693,0.96571 -0.9736,0.96571 0,0 -0.4457,-0.43807 -0.9811,-0.9735 z"
|
||||
id="path3399"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -923.27903,396.77639 0,-2.02518 3.2037,-5.3394 3.2036,-5.33941 0.9135,0 0.9134,0 0,2.02331 0,2.02331 -3.2051,5.34097 -3.2052,5.34093 -0.9119,0 -0.912,0 0,-2.0252 z"
|
||||
id="path3393"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -926.64593,380.38988 -0.9733,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9773,-0.97724 0.9697,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9736,0.9735 -0.9734,-0.97384 z"
|
||||
id="path3385"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -910.27363,377.26274 0,-2.02282 3.2052,-5.3417 3.2052,-5.34171 0.9119,-6e-5 0.9119,-6e-5 0,2.02518 0,2.02521 -3.2036,5.3394 -3.2036,5.33941 -0.9135,0 -0.9135,0 0,-2.02282 z"
|
||||
id="path3377"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -958.32118,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z"
|
||||
id="path3371"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -945.31583,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96961 -0.96951,0.96964 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
id="path3369"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -947.57453,399.89817 -0.9657,-0.96584 0,-7.50313 0,-7.5031 0.9696,-0.96955 0.9696,-0.96954 0.9697,0.96954 0.9696,0.96955 0,7.50319 0,7.50322 -0.9658,0.96575 c -0.5312,0.53114 -0.96929,0.96572 -0.97349,0.96572 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z"
|
||||
id="path3365"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -934.56913,399.89817 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9736,-0.9735 0.9736,-0.97351 0.9733,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.53539,0.53537 -0.97699,0.97341 -0.98119,0.97341 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z"
|
||||
id="path3363"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -947.57453,380.39788 -0.9657,-0.96584 0,-7.5031 0,-7.50312 0.9696,-0.96955 0.9696,-0.96955 0.9697,0.96955 0.9696,0.96955 0,7.50322 0,7.50319 -0.9658,0.96574 c -0.5312,0.53114 -0.96929,0.96575 -0.97349,0.96575 -0.01,0 -0.44231,-0.43464 -0.9735,-0.96584 z"
|
||||
id="path3351"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -934.56133,380.38988 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.97339,0.9738 -0.9735,-0.97359 z"
|
||||
id="path3349"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -958.32118,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z"
|
||||
id="path3343"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -945.31583,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96964 -0.96951,0.96961 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
id="path4610-4-6"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -892.70413,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z"
|
||||
id="path3431"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -873.12673,393.45965 -3.2051,-5.34195 0,-2.02266 0,-2.02264 0.9134,0 0.9135,0 3.2036,5.33941 3.2037,5.3394 0,2.02518 0,2.02521 -0.912,0 -0.9119,0 -3.20519,-5.34195 z"
|
||||
id="path3423"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -890.44163,382.65253 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.2479,0 4.248,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.248,0 -0.9734,-0.97353 z"
|
||||
id="path3421"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -877.43623,382.65253 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.248,0 4.2479,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.2479,0 -0.97349,-0.97353 z"
|
||||
id="path3419"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -892.70413,380.38988 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z"
|
||||
id="path3417"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -866.67783,380.38988 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.97349,0.97381 -0.9734,0.9738 -0.9735,-0.97359 z"
|
||||
id="path3413"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -890.43773,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z"
|
||||
id="path3407"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -877.43233,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
id="path4610-1-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.6 KiB |
@@ -1,186 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="31.177315mm"
|
||||
height="14.907915mm"
|
||||
viewBox="0 0 110.4708 52.823321"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="segments_qwe.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="12.310946"
|
||||
inkscape:cx="55.23539"
|
||||
inkscape:cy="26.411671"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="false"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1144"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(967.89459,-355.26718)">
|
||||
<rect
|
||||
style="opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="rect4658"
|
||||
width="110.4708"
|
||||
height="52.823322"
|
||||
x="-967.89459"
|
||||
y="355.26718"
|
||||
ry="2.2743988" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -926.64583,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9733,-0.97384 0.9734,-0.97384 0.9736,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5313,0.53114 -0.9693,0.96571 -0.9736,0.96571 0,0 -0.4457,-0.43807 -0.9811,-0.9735 z"
|
||||
id="path4765"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -900.62733,399.89817 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9735,-0.9735 0.9736,-0.97351 0.9734,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.5355,0.53537 -0.977,0.97341 -0.9813,0.97341 -0.01,0 -0.4422,-0.43461 -0.9734,-0.96581 z"
|
||||
id="path4761"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -923.27903,396.77639 0,-2.02518 3.2037,-5.3394 3.2036,-5.33941 0.9135,0 0.9134,0 0,2.02331 0,2.02331 -3.2051,5.34097 -3.2052,5.34093 -0.9119,0 -0.912,0 0,-2.0252 z"
|
||||
id="path4759"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -907.06843,393.45965 -3.2052,-5.34195 0,-2.02266 0,-2.02264 0.9135,0 0.9135,0 3.2036,5.33941 3.2036,5.3394 0,2.02518 0,2.02521 -0.9119,0 -0.91189,0 -3.2052,-5.34195 z"
|
||||
id="path4757"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -926.64593,380.38988 -0.9733,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9773,-0.97724 0.9697,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9736,0.9735 -0.9734,-0.97384 z"
|
||||
id="path4751"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -900.61953,380.38988 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9696,-0.96955 0.9774,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.9735,0.9738 -0.97339,-0.97359 z"
|
||||
id="path4747"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -958.32118,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z"
|
||||
id="path4737"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -945.31583,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96961 -0.96951,0.96964 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
id="path4735"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -960.58758,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z"
|
||||
id="path4733"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -934.56913,399.89817 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9736,-0.9735 0.9736,-0.97351 0.9733,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.53539,0.53537 -0.97699,0.97341 -0.98119,0.97341 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z"
|
||||
id="path4729"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -941.01023,393.45965 -3.2051,-5.34195 0,-2.02266 0,-2.02264 0.9134,0 0.9135,0 3.2036,5.33941 3.2037,5.3394 0,2.02518 0,2.02521 -0.912,0 -0.9119,0 -3.2052,-5.34195 z"
|
||||
id="path4725"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -960.58758,380.38988 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z"
|
||||
id="path4719"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -934.56133,380.38988 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.97339,0.9738 -0.9735,-0.97359 z"
|
||||
id="path4715"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -958.32118,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z"
|
||||
id="path4709"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -945.31583,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96964 -0.96951,0.96961 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
id="path4610-4-6"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -890.43773,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z"
|
||||
id="path4801"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -877.43233,402.15653 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96961 -0.9695,0.96964 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
id="path4799"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -892.70413,399.89017 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z"
|
||||
id="path4797"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -890.44163,382.65253 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.2479,0 4.248,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.248,0 -0.9734,-0.97353 z"
|
||||
id="path4787"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -892.70413,380.38988 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z"
|
||||
id="path4783"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -890.43773,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z"
|
||||
id="path4773"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1"
|
||||
d="m -877.43233,363.14038 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
id="path4610-1-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.2 KiB |
@@ -1,95 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="31.177315mm"
|
||||
height="14.907915mm"
|
||||
viewBox="0 0 110.4708 52.823321"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="segments_template.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="12.310946"
|
||||
inkscape:cx="55.235392"
|
||||
inkscape:cy="26.411669"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:object-paths="false"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1144"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(967.89459,-355.26718)">
|
||||
<rect
|
||||
style="opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="rect4658"
|
||||
width="110.4708"
|
||||
height="52.823322"
|
||||
x="-967.89459"
|
||||
y="355.26718"
|
||||
ry="2.2743988" />
|
||||
<g
|
||||
id="g4660"
|
||||
transform="translate(0.78135242,3.819203)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4610-2"
|
||||
d="m -925.16078,398.33733 -0.9696,-0.96964 0.9696,-0.96961 0.9695,-0.96964 4.248,0 4.248,0 0.9696,0.96964 0.9695,0.96961 -0.9695,0.96964 -0.9696,0.96964 -4.248,0 -4.248,0 -0.9695,-0.96964 z m 13.0054,0 -0.9696,-0.96964 0.9696,-0.96961 0.9695,-0.96964 4.248,0 4.2481,0 0.9695,0.96964 0.9695,0.96961 -0.9695,0.96964 -0.9695,0.96964 -4.2481,0 -4.248,0 -0.9695,-0.96964 z m -15.2718,-2.26636 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9733,-0.97384 0.9734,-0.97384 0.9736,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5313,0.53114 -0.9693,0.96571 -0.9736,0.96571 0,0 -0.4457,-0.43807 -0.9811,-0.9735 z m 13.0131,0.008 -0.9657,-0.96584 0,-7.50313 0,-7.5031 0.9696,-0.96955 0.9696,-0.96954 0.9697,0.96954 0.9696,0.96955 0,7.50319 0,7.50322 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96572 -0.9736,0.96572 -0.01,0 -0.4422,-0.43461 -0.9734,-0.96581 z m 13.0054,0 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9735,-0.9735 0.9736,-0.97351 0.9734,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.5355,0.53537 -0.977,0.97341 -0.9813,0.97341 -0.01,0 -0.4422,-0.43461 -0.9734,-0.96581 z m -22.6517,-3.12178 0,-2.02518 3.2037,-5.3394 3.2036,-5.33941 0.9135,0 0.9134,0 0,2.02331 0,2.02331 -3.2051,5.34097 -3.2052,5.34093 -0.9119,0 -0.912,0 0,-2.0252 z m 16.2106,-3.31674 -3.2052,-5.34195 0,-2.02266 0,-2.02264 0.9135,0 0.9135,0 3.2036,5.33941 3.2036,5.3394 0,2.02518 0,2.02521 -0.9119,0 -0.91189,0 -3.2052,-5.34195 z m -17.3149,-10.80712 -0.9735,-0.97354 0.9736,-0.9734 0.9735,-0.97344 4.2479,0 4.2479,0 0.9735,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.248,0 -4.2479,0 -0.9734,-0.97353 z m 13.0054,0 -0.9735,-0.97354 0.9736,-0.9734 0.9735,-0.97344 4.2479,0 4.248,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.248,0 -4.2479,0 -0.9734,-0.97353 z m -15.268,-2.26265 -0.9733,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9773,-0.97724 0.9697,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9736,0.9735 -0.9734,-0.97384 z m 13.0132,0.008 -0.9657,-0.96584 0,-7.5031 0,-7.50312 0.9696,-0.96955 0.9696,-0.96955 0.9697,0.96955 0.9696,0.96955 0,7.50322 0,7.50319 -0.9658,0.96574 c -0.5312,0.53114 -0.9693,0.96575 -0.9736,0.96575 -0.01,0 -0.4422,-0.43464 -0.9734,-0.96584 z m 13.0132,-0.008 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9696,-0.96955 0.9774,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.9735,0.9738 -0.97339,-0.97359 z m -19.4558,-6.44373 -3.2037,-5.33941 0,-2.02517 0,-2.02521 0.912,0 0.9119,0 3.2052,5.34054 3.2051,5.34057 0,2.02343 0,2.02346 -0.9134,0 -0.9135,0 -3.2036,-5.3394 z m 9.8017,3.31659 0,-2.02282 3.2052,-5.3417 3.2052,-5.34171 0.9119,-6e-5 0.9119,-6e-5 0,2.02518 0,2.02521 -3.2036,5.3394 -3.2036,5.33941 -0.9135,0 -0.9135,0 0,-2.02282 z m -14.1058,-14.12236 -0.9696,-0.96961 0.9696,-0.96964 0.9695,-0.96964 4.248,0 4.248,0 0.9696,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.9696,0.96964 -4.248,0 -4.248,0 -0.9695,-0.96964 z m 13.0054,0 -0.9696,-0.96961 0.9696,-0.96964 0.9695,-0.96964 4.248,0 4.2481,0 0.9695,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.9695,0.96964 -4.2481,0 -4.248,0 -0.9695,-0.96964 z"
|
||||
style="fill:#ff0000;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4610-4-6"
|
||||
d="m -959.10253,398.33733 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z m 13.00535,0 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96961 -0.96951,0.96964 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z m -15.27175,-2.26636 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z m 13.01305,0.008 -0.9657,-0.96584 0,-7.50313 0,-7.5031 0.9696,-0.96955 0.9696,-0.96954 0.9697,0.96954 0.9696,0.96955 0,7.50319 0,7.50322 -0.9658,0.96575 c -0.5312,0.53114 -0.96929,0.96572 -0.97349,0.96572 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z m 13.0054,0 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9736,-0.9735 0.9736,-0.97351 0.9733,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.9735,0.97344 c -0.53539,0.53537 -0.97699,0.97341 -0.98119,0.97341 -0.01,0 -0.44231,-0.43461 -0.9735,-0.96581 z m -22.65155,-3.12178 0,-2.02518 3.2036,-5.3394 3.20355,-5.33941 0.9135,0 0.9135,0 0,2.02331 0,2.02331 -3.20515,5.34097 -3.2052,5.34093 -0.9119,0 -0.9119,0 0,-2.0252 z m 16.21045,-3.31674 -3.2051,-5.34195 0,-2.02266 0,-2.02264 0.9134,0 0.9135,0 3.2036,5.33941 3.2037,5.3394 0,2.02518 0,2.02521 -0.912,0 -0.9119,0 -3.2052,-5.34195 z m -17.31485,-10.80712 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.2479,0 4.24795,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.24785,0 -4.248,0 -0.9734,-0.97353 z m 13.00535,0 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.248,0 4.2479,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.2479,0 -0.97349,-0.97353 z m -15.26785,-2.26265 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z m 13.01305,0.008 -0.9657,-0.96584 0,-7.5031 0,-7.50312 0.9696,-0.96955 0.9696,-0.96955 0.9697,0.96955 0.9696,0.96955 0,7.50322 0,7.50319 -0.9658,0.96574 c -0.5312,0.53114 -0.96929,0.96575 -0.97349,0.96575 -0.01,0 -0.44231,-0.43464 -0.9735,-0.96584 z m 13.0132,-0.008 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.9735,0.97381 -0.97339,0.9738 -0.9735,-0.97359 z m -19.45575,-6.44373 -3.2036,-5.33941 0,-2.02517 0,-2.02521 0.9119,0 0.9119,0 3.2052,5.34054 3.20515,5.34057 0,2.02343 0,2.02346 -0.9135,0 -0.9135,0 -3.20355,-5.3394 z m 9.80175,3.31659 0,-2.02282 3.2051,-5.3417 3.2052,-5.34171 0.9119,-6e-5 0.912,-6e-5 0,2.02518 0,2.02521 -3.2037,5.3394 -3.2036,5.33941 -0.9135,0 -0.9134,0 0,-2.02282 z m -14.10585,-14.12236 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.24795,0 0.9695,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.9695,0.96964 -4.24795,0 -4.2481,0 -0.9695,-0.96964 z m 13.00535,0 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.9695,0.96964 0.96951,0.96964 -0.96951,0.96961 -0.9695,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
style="fill:#ff0000;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4610-1-5"
|
||||
d="m -891.21908,398.33733 -0.9695,-0.96964 0.9695,-0.96961 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96961 -0.9696,0.96964 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z m 13.0054,0 -0.9695,-0.96964 0.9695,-0.96961 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96961 -0.9695,0.96964 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z m -15.2718,-2.26636 -0.9734,-0.97353 0,-7.48741 0,-7.48737 0.9734,-0.97384 0.9734,-0.97384 0.9735,0.9735 0.9736,0.9735 0,7.4955 0,7.49553 -0.9658,0.96575 c -0.5312,0.53114 -0.9693,0.96571 -0.9735,0.96571 0,0 -0.4458,-0.43807 -0.9812,-0.9735 z m 13.0131,0.008 -0.9657,-0.96584 0,-7.50313 0,-7.5031 0.9696,-0.96955 0.9696,-0.96954 0.9697,0.96954 0.9696,0.96955 0,7.50319 0,7.50322 -0.96579,0.96575 c -0.53121,0.53114 -0.9693,0.96572 -0.9735,0.96572 -0.01,0 -0.4423,-0.43461 -0.9735,-0.96581 z m 13.0054,0 -0.9657,-0.96584 0,-7.49544 0,-7.4954 0.9736,-0.9735 0.9736,-0.97351 0.9733,0.97384 0.9734,0.97384 0,7.48747 0,7.4875 -0.97349,0.97344 c -0.5354,0.53537 -0.977,0.97341 -0.9812,0.97341 -0.01,0 -0.4423,-0.43461 -0.9735,-0.96581 z m -22.6516,-3.12178 0,-2.02518 3.2036,-5.3394 3.2036,-5.33941 0.9135,0 0.9135,0 0,2.02331 0,2.02331 -3.2052,5.34097 -3.2052,5.34093 -0.91189,0 -0.9119,0 0,-2.0252 z m 16.2105,-3.31674 -3.2051,-5.34195 0,-2.02266 0,-2.02264 0.9134,0 0.9135,0 3.2036,5.33941 3.2037,5.3394 0,2.02518 0,2.02521 -0.912,0 -0.9119,0 -3.20519,-5.34195 z m -17.3149,-10.80712 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.2479,0 4.248,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.248,0 -0.9734,-0.97353 z m 13.0054,0 -0.9734,-0.97354 0.9735,-0.9734 0.9735,-0.97344 4.248,0 4.2479,0 0.9734,0.97353 0.9734,0.9735 -0.9735,0.97344 -0.9735,0.97344 -4.2479,0 -4.2479,0 -0.97349,-0.97353 z m -15.2679,-2.26265 -0.9734,-0.97384 0,-7.48747 0,-7.4875 0.9773,-0.97724 0.9774,-0.97724 0.9696,0.96955 0.9696,0.96955 0,7.4955 0,7.49553 -0.9736,0.9735 -0.9735,0.9735 -0.9734,-0.97384 z m 13.0131,0.008 -0.9657,-0.96584 0,-7.5031 0,-7.50312 0.9696,-0.96955 0.9696,-0.96955 0.9697,0.96955 0.9696,0.96955 0,7.50322 0,7.50319 -0.96579,0.96574 c -0.53121,0.53114 -0.9693,0.96575 -0.9735,0.96575 -0.01,0 -0.4423,-0.43464 -0.9735,-0.96584 z m 13.0132,-0.008 -0.9735,-0.97359 0,-7.49544 0,-7.49541 0.9696,-0.96954 0.9697,-0.96955 0.9773,0.97724 0.9773,0.97724 0,7.48753 0,7.4875 -0.97349,0.97381 -0.9734,0.9738 -0.9735,-0.97359 z m -19.4558,-6.44373 -3.2036,-5.33941 0,-2.02517 0,-2.02521 0.9119,0 0.9119,0 3.2052,5.34054 3.2052,5.34057 0,2.02343 0,2.02346 -0.9135,0 -0.9135,0 -3.2036,-5.3394 z m 9.8018,3.31659 0,-2.02282 3.2051,-5.3417 3.2052,-5.34171 0.9119,-6e-5 0.912,-6e-5 0,2.02518 0,2.02521 -3.2037,5.3394 -3.2036,5.33941 -0.9135,0 -0.9134,0 0,-2.02282 z m -14.1059,-14.12236 -0.9695,-0.96961 0.9695,-0.96964 0.9695,-0.96964 4.2481,0 4.248,0 0.96951,0.96964 0.9696,0.96964 -0.9696,0.96961 -0.96951,0.96964 -4.248,0 -4.2481,0 -0.9695,-0.96964 z m 13.0054,0 -0.9695,-0.96961 0.9695,-0.96964 0.9696,-0.96964 4.248,0 4.248,0 0.96951,0.96964 0.9695,0.96964 -0.9695,0.96961 -0.96951,0.96964 -4.248,0 -4.248,0 -0.9696,-0.96964 z"
|
||||
style="fill:#ff0000;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB |
@@ -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);
|
||||
})();
|
||||
|
||||
266
packages/usb/package-lock.json
generated
@@ -19,6 +19,12 @@ let config = {
|
||||
'sprite': 'compiled_sprite.svg',
|
||||
bust: false
|
||||
}
|
||||
},
|
||||
svg: { // General options for created SVG files
|
||||
namespaceIDs: true,
|
||||
rootAttributes: {
|
||||
"xmlns:xlink":"http://www.w3.org/1999/xlink"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||