diff --git a/packages/uhk-web/src/app/components/svg/constants.ts b/packages/uhk-web/src/app/components/svg/constants.ts new file mode 100644 index 00000000..e77a6602 --- /dev/null +++ b/packages/uhk-web/src/app/components/svg/constants.ts @@ -0,0 +1 @@ +export const SECONDARY_ROLE_BOTTOM_MARGIN = 1; diff --git a/packages/uhk-web/src/app/components/svg/keys/index.ts b/packages/uhk-web/src/app/components/svg/keys/index.ts index d4378df4..0af88ec5 100644 --- a/packages/uhk-web/src/app/components/svg/keys/index.ts +++ b/packages/uhk-web/src/app/components/svg/keys/index.ts @@ -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'; diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-icon-text-key/svg-icon-text-key.component.html b/packages/uhk-web/src/app/components/svg/keys/svg-icon-text-key/svg-icon-text-key.component.html index 256a7c72..a490e5fc 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-icon-text-key/svg-icon-text-key.component.html +++ b/packages/uhk-web/src/app/components/svg/keys/svg-icon-text-key/svg-icon-text-key.component.html @@ -10,4 +10,11 @@ [attr.text-anchor]="'middle'" [attr.font-size]="11"> {{ text }} - \ No newline at end of file + + + diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-icon-text-key/svg-icon-text-key.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-icon-text-key/svg-icon-text-key.component.ts index 21451a50..151880b7 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-icon-text-key/svg-icon-text-key.component.ts +++ b/packages/uhk-web/src/app/components/svg/keys/svg-icon-text-key/svg-icon-text-key.component.ts @@ -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; } } diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.html b/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.html index 74250d49..3564a318 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.html +++ b/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.html @@ -25,34 +25,40 @@ + [keystrokeAction]="labelSource" + [secondaryText]="secondaryText"> + [text]="labelSource" + [secondaryText]="secondaryText"> + [texts]="labelSource" + [secondaryText]="secondaryText"> + [icon]="labelSource.icon" + [secondaryText]="secondaryText"> + [text]="labelSource.text" + [secondaryText]="secondaryText"> + [icon]="labelSource" + [secondaryText]="secondaryText"> + [texts]="labelSource" + [secondaryText]="subComponentSecondaryRoleText"> S + + diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-keystroke-key/svg-keystroke-key.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-keystroke-key/svg-keystroke-key.component.ts index 6b1db082..6a9f4b55 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-keystroke-key/svg-keystroke-key.component.ts +++ b/packages/uhk-web/src/app/components/svg/keys/svg-keystroke-key/svg-keystroke-key.component.ts @@ -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); - - } - } diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-one-line-text-key/svg-one-line-text-key.component.html b/packages/uhk-web/src/app/components/svg/keys/svg-one-line-text-key/svg-one-line-text-key.component.html index b61b1bd1..23ceb4e7 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-one-line-text-key/svg-one-line-text-key.component.html +++ b/packages/uhk-web/src/app/components/svg/keys/svg-one-line-text-key/svg-one-line-text-key.component.html @@ -1,6 +1,13 @@ - - {{ text }} - \ No newline at end of file + {{ text }} + + + diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-one-line-text-key/svg-one-line-text-key.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-one-line-text-key/svg-one-line-text-key.component.ts index bf2c9fa8..1efe68aa 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-one-line-text-key/svg-one-line-text-key.component.ts +++ b/packages/uhk-web/src/app/components/svg/keys/svg-one-line-text-key/svg-one-line-text-key.component.ts @@ -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; } } diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/index.ts b/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/index.ts new file mode 100644 index 00000000..e420aebc --- /dev/null +++ b/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/index.ts @@ -0,0 +1 @@ +export * from './svg-secondary-role.component'; diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/svg-secondary-role.component.html b/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/svg-secondary-role.component.html new file mode 100644 index 00000000..9df82777 --- /dev/null +++ b/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/svg-secondary-role.component.html @@ -0,0 +1,15 @@ + + + + + 2 + + + + {{ text }} + + + diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/svg-secondary-role.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/svg-secondary-role.component.ts new file mode 100644 index 00000000..242792c3 --- /dev/null +++ b/packages/uhk-web/src/app/components/svg/keys/svg-secondary-role/svg-secondary-role.component.ts @@ -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)`; + } +} diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-single-icon-key/svg-single-icon-key.component.html b/packages/uhk-web/src/app/components/svg/keys/svg-single-icon-key/svg-single-icon-key.component.html index 82079540..27ca865b 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-single-icon-key/svg-single-icon-key.component.html +++ b/packages/uhk-web/src/app/components/svg/keys/svg-single-icon-key/svg-single-icon-key.component.html @@ -4,3 +4,10 @@ [attr.x]="svgWidth" [attr.y]="svgHeight"> + + diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-single-icon-key/svg-single-icon-key.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-single-icon-key/svg-single-icon-key.component.ts index 57f7618f..5a4c04f3 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-single-icon-key/svg-single-icon-key.component.ts +++ b/packages/uhk-web/src/app/components/svg/keys/svg-single-icon-key/svg-single-icon-key.component.ts @@ -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; } } diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-text-icon-key/svg-text-icon-key.component.html b/packages/uhk-web/src/app/components/svg/keys/svg-text-icon-key/svg-text-icon-key.component.html index 78fca459..4525fa2a 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-text-icon-key/svg-text-icon-key.component.html +++ b/packages/uhk-web/src/app/components/svg/keys/svg-text-icon-key/svg-text-icon-key.component.html @@ -9,4 +9,11 @@ [attr.height]="useHeight" [attr.x]="useX" [attr.y]="useY"> - \ No newline at end of file + + + diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-text-icon-key/svg-text-icon-key.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-text-icon-key/svg-text-icon-key.component.ts index 134035b8..741fe886 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-text-icon-key/svg-text-icon-key.component.ts +++ b/packages/uhk-web/src/app/components/svg/keys/svg-text-icon-key/svg-text-icon-key.component.ts @@ -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; } } diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-two-line-text-key/svg-two-line-text-key.component.html b/packages/uhk-web/src/app/components/svg/keys/svg-two-line-text-key/svg-two-line-text-key.component.html index 54d92406..2f866697 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-two-line-text-key/svg-two-line-text-key.component.html +++ b/packages/uhk-web/src/app/components/svg/keys/svg-two-line-text-key/svg-two-line-text-key.component.html @@ -8,4 +8,11 @@ [attr.y]="spanYs[index]" dy="0" >{{ text }} - \ No newline at end of file + + + diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-two-line-text-key/svg-two-line-text-key.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-two-line-text-key/svg-two-line-text-key.component.ts index 4ab3bddc..ade8fc84 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-two-line-text-key/svg-two-line-text-key.component.ts +++ b/packages/uhk-web/src/app/components/svg/keys/svg-two-line-text-key/svg-two-line-text-key.component.ts @@ -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; } } diff --git a/packages/uhk-web/src/app/components/svg/keys/util.ts b/packages/uhk-web/src/app/components/svg/keys/util.ts new file mode 100644 index 00000000..94735f34 --- /dev/null +++ b/packages/uhk-web/src/app/components/svg/keys/util.ts @@ -0,0 +1,3 @@ +export const isRectangleAsSecondaryRoleKey = (width: number, height: number): boolean => { + return width > height * 2.4; +}; diff --git a/packages/uhk-web/src/app/services/mapper.service.ts b/packages/uhk-web/src/app/services/mapper.service.ts index 2ba0e5e5..12a1e72d 100644 --- a/packages/uhk-web/src/app/services/mapper.service.ts +++ b/packages/uhk-web/src/app/services/mapper.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { KeystrokeType } from 'uhk-common'; +import { KeystrokeType, SecondaryRoleAction } from 'uhk-common'; import { Subscription } from 'rxjs/Subscription'; import { AppState, getOperatingSystem } from '../store'; @@ -18,6 +18,7 @@ export class MapperService { private systemScancodeIcons: Map; private nameToFileName: Map; private osSpecificTexts: Map; + private secondaryRoleTexts: Map; private operatingSystem: OperatingSystem; private osSubscription: Subscription; @@ -31,6 +32,7 @@ export class MapperService { this.initScanCodeTextMap(); this.initScancodeIcons(); this.initNameToFileNames(); + this.initSecondaryRoleTexts(); }); } @@ -118,6 +120,10 @@ export class MapperService { return text ? text : key; } + public getSecondaryRoleText(secondaryRoleAction: SecondaryRoleAction): string { + return this.secondaryRoleTexts.get(secondaryRoleAction); + } + private initOsSpecificText(): void { this.osSpecificTexts = new Map(); @@ -328,4 +334,18 @@ export class MapperService { this.nameToFileName.set('scroll-up', 'icon-kbd__mouse--scroll-up'); } + private initSecondaryRoleTexts(): void { + this.secondaryRoleTexts = new Map(); + 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'); + } } diff --git a/packages/uhk-web/src/app/shared.module.ts b/packages/uhk-web/src/app/shared.module.ts index c03afe70..93b45ee7 100644 --- a/packages/uhk-web/src/app/shared.module.ts +++ b/packages/uhk-web/src/app/shared.module.ts @@ -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,