Render key modifiers
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
|
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 { MacroComponent } from './components/macro/macro.component';
|
||||||
import { LegacyLoaderComponent } from './components/legacy/legacy-loader.component';
|
import { LegacyLoaderComponent } from './components/legacy/legacy-loader.component';
|
||||||
import { NotificationComponent } from './components/notification/notification.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({
|
@NgModule({
|
||||||
declarations: [MainAppComponent, KeymapComponent, MacroComponent, LegacyLoaderComponent, NotificationComponent],
|
declarations: [
|
||||||
|
MainAppComponent,
|
||||||
|
KeymapComponent,
|
||||||
|
MacroComponent,
|
||||||
|
LegacyLoaderComponent,
|
||||||
|
NotificationComponent,
|
||||||
|
SvgKeystrokeKeyComponent,
|
||||||
|
SvgOneLineTextKeyComponent,
|
||||||
|
SvgTwoLineTextKeyComponent
|
||||||
|
],
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
providers: [
|
providers: [
|
||||||
DataProviderService,
|
DataProviderService,
|
||||||
|
|||||||
@@ -7,6 +7,11 @@
|
|||||||
[attr.font-family]="'Helvetica'"
|
[attr.font-family]="'Helvetica'"
|
||||||
[attr.fill]="'white'"
|
[attr.fill]="'white'"
|
||||||
style="dominant-baseline: central">
|
style="dominant-baseline: central">
|
||||||
|
<svg:g svg-keystroke-key *ngSwitchCase="enumLabelTypes.KeystrokeKey"
|
||||||
|
[height]="height"
|
||||||
|
[width]="width"
|
||||||
|
[keystrokeAction]="labelSource">
|
||||||
|
</svg:g>
|
||||||
<svg:g svg-one-line-text-key *ngSwitchCase="enumLabelTypes.OneLineText"
|
<svg:g svg-one-line-text-key *ngSwitchCase="enumLabelTypes.OneLineText"
|
||||||
[height]="height"
|
[height]="height"
|
||||||
[width]="width"
|
[width]="width"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -1,5 +1,4 @@
|
|||||||
import { Component, OnInit, Input, OnChanges, SimpleChange } from '@angular/core';
|
import { Component, OnInit, Input, OnChanges, SimpleChange } from '@angular/core';
|
||||||
import {NgSwitch, NgSwitchCase} from '@angular/common';
|
|
||||||
|
|
||||||
import {KeyAction} from '../../../../config-serializer/config-items/KeyAction';
|
import {KeyAction} from '../../../../config-serializer/config-items/KeyAction';
|
||||||
import {KeystrokeAction} from '../../../../config-serializer/config-items/KeystrokeAction';
|
import {KeystrokeAction} from '../../../../config-serializer/config-items/KeystrokeAction';
|
||||||
@@ -11,14 +10,13 @@ import {UhkConfiguration} from '../../../../config-serializer/config-items/UhkCo
|
|||||||
import {UhkConfigurationService} from '../../../services/uhk-configuration.service';
|
import {UhkConfigurationService} from '../../../services/uhk-configuration.service';
|
||||||
import {MapperService} from '../../../services/mapper.service';
|
import {MapperService} from '../../../services/mapper.service';
|
||||||
|
|
||||||
import {SvgOneLineTextKeyComponent} from './svg-one-line-text-key.component';
|
|
||||||
import {SvgTwoLineTextKeyComponent} from './svg-two-line-text-key.component';
|
|
||||||
import {SvgSingleIconKeyComponent} from './svg-single-icon-key.component';
|
import {SvgSingleIconKeyComponent} from './svg-single-icon-key.component';
|
||||||
import {SvgTextIconKeyComponent} from './svg-text-icon-key.component';
|
import {SvgTextIconKeyComponent} from './svg-text-icon-key.component';
|
||||||
import {SvgIconTextKeyComponent} from './svg-icon-text-key.component';
|
import {SvgIconTextKeyComponent} from './svg-icon-text-key.component';
|
||||||
import {SvgSwitchKeymapKeyComponent} from './svg-switch-keymap-key.component';
|
import {SvgSwitchKeymapKeyComponent} from './svg-switch-keymap-key.component';
|
||||||
|
|
||||||
enum LabelTypes {
|
enum LabelTypes {
|
||||||
|
KeystrokeKey,
|
||||||
OneLineText,
|
OneLineText,
|
||||||
TwoLineText,
|
TwoLineText,
|
||||||
TextIcon,
|
TextIcon,
|
||||||
@@ -32,10 +30,6 @@ enum LabelTypes {
|
|||||||
template: require('./svg-keyboard-key.component.html'),
|
template: require('./svg-keyboard-key.component.html'),
|
||||||
directives:
|
directives:
|
||||||
[
|
[
|
||||||
NgSwitch,
|
|
||||||
NgSwitchCase,
|
|
||||||
SvgOneLineTextKeyComponent,
|
|
||||||
SvgTwoLineTextKeyComponent,
|
|
||||||
SvgSingleIconKeyComponent,
|
SvgSingleIconKeyComponent,
|
||||||
SvgTextIconKeyComponent,
|
SvgTextIconKeyComponent,
|
||||||
SvgIconTextKeyComponent,
|
SvgIconTextKeyComponent,
|
||||||
@@ -85,7 +79,7 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges {
|
|||||||
let keyAction: KeystrokeAction = this.keyAction as KeystrokeAction;
|
let keyAction: KeystrokeAction = this.keyAction as KeystrokeAction;
|
||||||
let newLabelSource: string[];
|
let newLabelSource: string[];
|
||||||
|
|
||||||
if (keyAction.hasScancode()) {
|
if (!keyAction.hasActiveModifier() && keyAction.hasScancode()) {
|
||||||
let scancode: number = keyAction.scancode;
|
let scancode: number = keyAction.scancode;
|
||||||
newLabelSource = this.mapperService.scanCodeToText(scancode);
|
newLabelSource = this.mapperService.scanCodeToText(scancode);
|
||||||
if (newLabelSource) {
|
if (newLabelSource) {
|
||||||
@@ -100,7 +94,7 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges {
|
|||||||
this.labelSource = this.mapperService.scanCodeToSvgImagePath(scancode);
|
this.labelSource = this.mapperService.scanCodeToSvgImagePath(scancode);
|
||||||
this.labelType = LabelTypes.SingleIcon;
|
this.labelType = LabelTypes.SingleIcon;
|
||||||
}
|
}
|
||||||
} else if (keyAction.hasOnlyOneActiveModifier()) {
|
} else if (keyAction.hasOnlyOneActiveModifier() && !keyAction.hasScancode()) {
|
||||||
newLabelSource = [];
|
newLabelSource = [];
|
||||||
switch (keyAction.modifierMask) {
|
switch (keyAction.modifierMask) {
|
||||||
case KeyModifiers.leftCtrl:
|
case KeyModifiers.leftCtrl:
|
||||||
@@ -125,7 +119,8 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
this.labelSource = newLabelSource;
|
this.labelSource = newLabelSource;
|
||||||
} else {
|
} else {
|
||||||
this.labelSource = undefined;
|
this.labelType = LabelTypes.KeystrokeKey;
|
||||||
|
this.labelSource = this.keyAction;
|
||||||
}
|
}
|
||||||
} else if (this.keyAction instanceof SwitchLayerAction) {
|
} else if (this.keyAction instanceof SwitchLayerAction) {
|
||||||
let keyAction: SwitchLayerAction = this.keyAction as SwitchLayerAction;
|
let keyAction: SwitchLayerAction = this.keyAction as SwitchLayerAction;
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './svg-keystroke-key.component';
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<svg [attr.viewBox]="viewBox" [attr.width]="textContainer.width" [attr.height]="textContainer.height"
|
||||||
|
[attr.x]="textContainer.x" [attr.y]="textContainer.y" [ngSwitch]="labelType">
|
||||||
|
<svg:g svg-one-line-text-key *ngSwitchCase="'one-line'"
|
||||||
|
[height]="height"
|
||||||
|
[width]="width"
|
||||||
|
[text]="labelSource">
|
||||||
|
</svg:g>
|
||||||
|
<svg:g svg-two-line-text-key *ngSwitchCase="'two-line'"
|
||||||
|
[height]="height"
|
||||||
|
[width]="width"
|
||||||
|
[texts]="labelSource">
|
||||||
|
</svg:g>
|
||||||
|
</svg>
|
||||||
|
<svg [attr.viewBox]="viewBox" [attr.width]="modifierContainer.width" [attr.height]="modifierContainer.height" [attr.x]="modifierContainer.x"
|
||||||
|
[attr.y]="modifierContainer.y" preserveAspectRatio="none">
|
||||||
|
<svg viewBox="0 0 100 100" [attr.width]="shift.width" [attr.height]="shift.height" [attr.x]="shift.x" [attr.y]="shift.y"
|
||||||
|
preserveAspectRatio="none" [class.disabled]="shift.disabled">
|
||||||
|
<svg:use [attr.xlink:href]="modifierIconNames.shift" />
|
||||||
|
</svg>
|
||||||
|
<svg viewBox="0 0 100 100" [attr.width]="control.width" [attr.height]="control.height" [attr.x]="control.x" [attr.y]="control.y"
|
||||||
|
preserveAspectRatio="none" [class.disabled]="control.disabled">
|
||||||
|
<svg:text [attr.text-anchor]="'middle'" [attr.x]="50" [attr.y]="50">C</svg:text>
|
||||||
|
</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>
|
||||||
|
<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>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
.disabled {
|
||||||
|
fill: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 100px;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -143,6 +143,9 @@ export class MapperService {
|
|||||||
this.nameToFileName.set('toggle', 'icon-kbd__fn--toggle');
|
this.nameToFileName.set('toggle', 'icon-kbd__fn--toggle');
|
||||||
this.nameToFileName.set('switch-keymap', 'icon-kbd__mod--switch-keymap');
|
this.nameToFileName.set('switch-keymap', 'icon-kbd__mod--switch-keymap');
|
||||||
this.nameToFileName.set('macro', 'icon-icon__macro');
|
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');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user