diff --git a/src/app.module.ts b/src/app.module.ts
index 6f8dca7a..0c5a7f07 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -1,4 +1,4 @@
-import { NgModule } from '@angular/core';
+import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
@@ -12,9 +12,22 @@ import { KeymapComponent } from './components/keymap/keymap.component';
import { MacroComponent } from './components/macro/macro.component';
import { LegacyLoaderComponent } from './components/legacy/legacy-loader.component';
import { NotificationComponent } from './components/notification/notification.component';
+import { SvgKeystrokeKeyComponent } from './components/svg/keys/svg-keystroke-key.component';
+import { SvgOneLineTextKeyComponent } from './components/svg/keys/svg-one-line-text-key.component';
+import { SvgTwoLineTextKeyComponent } from './components/svg/keys/svg-two-line-text-key.component';
+
@NgModule({
- declarations: [MainAppComponent, KeymapComponent, MacroComponent, LegacyLoaderComponent, NotificationComponent],
+ declarations: [
+ MainAppComponent,
+ KeymapComponent,
+ MacroComponent,
+ LegacyLoaderComponent,
+ NotificationComponent,
+ SvgKeystrokeKeyComponent,
+ SvgOneLineTextKeyComponent,
+ SvgTwoLineTextKeyComponent
+ ],
imports: [BrowserModule],
providers: [
DataProviderService,
diff --git a/src/components/svg/keys/svg-keyboard-key.component.html b/src/components/svg/keys/svg-keyboard-key.component.html
index 5fbcf4eb..9b66cb9a 100644
--- a/src/components/svg/keys/svg-keyboard-key.component.html
+++ b/src/components/svg/keys/svg-keyboard-key.component.html
@@ -7,6 +7,11 @@
[attr.font-family]="'Helvetica'"
[attr.fill]="'white'"
style="dominant-baseline: central">
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/svg/keys/svg-keystroke-key.component/svg-keystroke-key.component.scss b/src/components/svg/keys/svg-keystroke-key.component/svg-keystroke-key.component.scss
new file mode 100644
index 00000000..54820e8e
--- /dev/null
+++ b/src/components/svg/keys/svg-keystroke-key.component/svg-keystroke-key.component.scss
@@ -0,0 +1,7 @@
+.disabled {
+ fill: gray;
+}
+
+text {
+ font-size: 100px;
+}
diff --git a/src/components/svg/keys/svg-keystroke-key.component/svg-keystroke-key.component.ts b/src/components/svg/keys/svg-keystroke-key.component/svg-keystroke-key.component.ts
new file mode 100644
index 00000000..04cd8ec7
--- /dev/null
+++ b/src/components/svg/keys/svg-keystroke-key.component/svg-keystroke-key.component.ts
@@ -0,0 +1,161 @@
+import { Component, OnInit, OnChanges, Input } from '@angular/core';
+
+import { KeystrokeAction } from '../../../../../config-serializer/config-items/KeystrokeAction';
+import { KeyModifiers } from '../../../../../config-serializer/config-items/KeyModifiers';
+import { MapperService } from '../../../../services/mapper.service';
+
+class SvgAttributes {
+ width: number;
+ height: number;
+ x: number;
+ y: number;
+ disabled: boolean;
+
+ constructor() {
+ this.width = 0;
+ this.height = 0;
+ this.x = 0;
+ this.y = 0;
+ this.disabled = true;
+ }
+}
+
+enum Modifiers {
+ Shift, Control, Alt, Command
+}
+
+@Component({
+ selector: 'g[svg-keystroke-key]',
+ template: require('./svg-keystroke-key.component.html'),
+ styles: [require('./svg-keystroke-key.component.scss')]
+})
+export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
+ @Input() height: number;
+ @Input() width: number;
+ @Input() keystrokeAction: KeystrokeAction;
+
+ private viewBox: string;
+ private textContainer: SvgAttributes;
+ private modifierContainer: SvgAttributes;
+ private shift: SvgAttributes;
+ private control: SvgAttributes;
+ private option: SvgAttributes;
+ private command: SvgAttributes;
+
+ private labelSource: any;
+ private labelType: 'empty' | 'one-line' | 'two-line' | 'icon';
+
+ private modifierIconNames: {
+ shift?: string,
+ option?: string,
+ command?: string
+ };
+
+ constructor(private mapper: MapperService) {
+ this.modifierIconNames = {};
+ this.textContainer = new SvgAttributes();
+ this.modifierContainer = new SvgAttributes();
+ this.shift = new SvgAttributes();
+ this.control = new SvgAttributes();
+ this.option = new SvgAttributes();
+ this.command = new SvgAttributes();
+ }
+
+ ngOnInit() {
+ 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');
+
+ let bottomSideMode: boolean = this.width < this.height * 1.8;
+
+ const heightWidthRatio = this.height / this.width;
+
+ if (bottomSideMode) {
+ const maxIconWidth = this.width / 4;
+ const maxIconHeight = this.height;
+ const iconScalingFactor = 0.8;
+ let iconWidth = iconScalingFactor * heightWidthRatio * maxIconWidth;
+ let iconHeight = iconScalingFactor * maxIconHeight;
+ this.modifierContainer.width = this.width;
+ this.modifierContainer.height = this.height / 5;
+ this.modifierContainer.y = this.height - this.modifierContainer.height;
+ this.shift.width = iconWidth;
+ this.shift.height = iconHeight;
+ this.shift.x = (maxIconWidth - iconWidth) / 2;
+ this.shift.y = (maxIconHeight - iconHeight) / 2;
+ this.control.width = iconWidth;
+ this.control.height = iconHeight;
+ this.control.x = this.shift.x + maxIconWidth;
+ this.control.y = this.shift.y;
+ this.option.width = iconWidth;
+ this.option.height = iconHeight;
+ this.option.x = this.control.x + maxIconWidth;
+ this.option.y = this.shift.y;
+ this.command.width = iconWidth;
+ this.command.height = iconHeight;
+ this.command.x = this.option.x + maxIconWidth;
+ this.command.y = this.shift.y;
+ this.textContainer.y = -this.modifierContainer.height / 2;
+ } else {
+ this.modifierContainer.width = this.width / 4;
+ this.modifierContainer.height = this.height;
+ this.modifierContainer.x = this.width - this.modifierContainer.width;
+
+ const length = Math.min(this.modifierContainer.width / 2, this.modifierContainer.height / 2);
+
+ const iconScalingFactor = 0.8;
+ const iconWidth = iconScalingFactor * this.width * (length / this.modifierContainer.width);
+ const iconHeight = iconScalingFactor * this.height * (length / this.modifierContainer.height);
+ this.shift.width = iconWidth;
+ this.shift.height = iconHeight;
+ this.shift.x = this.width / 4 - iconWidth / 2;
+ this.shift.y = this.height / 4 - iconHeight / 2;
+ this.control.width = iconWidth;
+ this.control.height = iconHeight;
+ this.control.x = this.shift.x + this.width / 2;
+ this.control.y = this.shift.y;
+ this.option.width = iconWidth;
+ this.option.height = iconHeight;
+ this.option.x = this.shift.x;
+ this.option.y = this.shift.y + this.height / 2;
+ this.command.width = iconWidth;
+ this.command.height = iconHeight;
+ this.command.x = this.option.x + this.width / 2;
+ this.command.y = this.option.y;
+ this.textContainer.x = -this.modifierContainer.width / 2;
+ }
+
+ this.textContainer.width = this.width;
+ this.textContainer.height = this.height;
+ }
+
+ ngOnChanges() {
+ let newLabelSource: string[];
+ if (this.keystrokeAction.hasScancode()) {
+ let scancode: number = this.keystrokeAction.scancode;
+ newLabelSource = this.mapper.scanCodeToText(scancode);
+ if (newLabelSource) {
+ if (newLabelSource.length === 1) {
+ this.labelSource = newLabelSource[0];
+ this.labelType = 'one-line';
+ } else {
+ this.labelSource = newLabelSource;
+ this.labelType = 'two-line';
+ }
+ } else {
+ this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode);
+ this.labelType = 'icon';
+ }
+ } 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);
+
+ }
+
+}
diff --git a/src/services/mapper.service.ts b/src/services/mapper.service.ts
index 6bbab7ee..eb182763 100644
--- a/src/services/mapper.service.ts
+++ b/src/services/mapper.service.ts
@@ -143,6 +143,9 @@ export class MapperService {
this.nameToFileName.set('toggle', 'icon-kbd__fn--toggle');
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');
}
}