Added positioning to the popover
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,39 @@
|
||||
<div class="arrowCustom"></div>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="popover-title menu-tabs">
|
||||
<ul class="nav nav-tabs popover-menu">
|
||||
<li #keypress [class.active]="activeTab === TabName.Keypress" (click)="selectTab(TabName.Keypress)">
|
||||
<li #keypress [class.active]="activeTab === tabName.Keypress" (click)="selectTab(tabName.Keypress)">
|
||||
<a class="menu-tabs--item">
|
||||
<i class="fa fa-keyboard-o"></i>
|
||||
<span>Keypress</span>
|
||||
</a>
|
||||
</li>
|
||||
<li #layer [class.active]="activeTab === TabName.Layer" (click)="selectTab(TabName.Layer)">
|
||||
<li #layer [class.active]="activeTab === tabName.Layer" (click)="selectTab(tabName.Layer)">
|
||||
<a class="menu-tabs--item">
|
||||
<i class="fa fa-clone"></i>
|
||||
<span>Layer</span>
|
||||
</a>
|
||||
</li>
|
||||
<li #mouse [class.active]="activeTab === TabName.Mouse" (click)="selectTab(TabName.Mouse)">
|
||||
<li #mouse [class.active]="activeTab === tabName.Mouse" (click)="selectTab(tabName.Mouse)">
|
||||
<a class="menu-tabs--item">
|
||||
<i class="fa fa-mouse-pointer"></i>
|
||||
<span>Mouse</span>
|
||||
</a>
|
||||
</li>
|
||||
<li #macro [class.active]="activeTab === TabName.Macro" (click)="selectTab(TabName.Macro)">
|
||||
<li #macro [class.active]="activeTab === tabName.Macro" (click)="selectTab(tabName.Macro)">
|
||||
<a class="menu-tabs--item">
|
||||
<i class="fa fa-play"></i>
|
||||
<span>Macro</span>
|
||||
</a>
|
||||
</li>
|
||||
<li #keymap [class.active]="activeTab === TabName.Keymap" (click)="selectTab(TabName.Keymap)">
|
||||
<li #keymap [class.active]="activeTab === tabName.Keymap" (click)="selectTab(tabName.Keymap)">
|
||||
<a class="menu-tabs--item">
|
||||
<i class="fa fa-keyboard-o"></i>
|
||||
<span>Keymap</span>
|
||||
</a>
|
||||
</li>
|
||||
<li #none [class.active]="activeTab === TabName.None" (click)="selectTab(TabName.None)">
|
||||
<li #none [class.active]="activeTab === tabName.None" (click)="selectTab(tabName.None)">
|
||||
<a class="menu-tabs--item">
|
||||
<i class="fa fa-ban"></i>
|
||||
<span>None</span>
|
||||
@@ -42,12 +43,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" [ngSwitch]="activeTab">
|
||||
<keypress-tab #tab *ngSwitchCase="TabName.Keypress" class="popover-content" [defaultKeyAction]="defaultKeyAction" [longPressEnabled]="true"></keypress-tab>
|
||||
<layer-tab #tab *ngSwitchCase="TabName.Layer" class="popover-content" [defaultKeyAction]="defaultKeyAction"></layer-tab>
|
||||
<mouse-tab #tab *ngSwitchCase="TabName.Mouse" class="popover-content" [defaultKeyAction]="defaultKeyAction"></mouse-tab>
|
||||
<macro-tab #tab *ngSwitchCase="TabName.Macro" class="popover-content" [defaultKeyAction]="defaultKeyAction"></macro-tab>
|
||||
<keymap-tab #tab *ngSwitchCase="TabName.Keymap" class="popover-content" [defaultKeyAction]="defaultKeyAction" [keymaps]="keymaps$ | async"></keymap-tab>
|
||||
<none-tab #tab *ngSwitchCase="TabName.None" class="popover-content"></none-tab>
|
||||
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content" [defaultKeyAction]="defaultKeyAction" [longPressEnabled]="true"></keypress-tab>
|
||||
<layer-tab #tab *ngSwitchCase="tabName.Layer" class="popover-content" [defaultKeyAction]="defaultKeyAction"></layer-tab>
|
||||
<mouse-tab #tab *ngSwitchCase="tabName.Mouse" class="popover-content" [defaultKeyAction]="defaultKeyAction"></mouse-tab>
|
||||
<macro-tab #tab *ngSwitchCase="tabName.Macro" class="popover-content" [defaultKeyAction]="defaultKeyAction"></macro-tab>
|
||||
<keymap-tab #tab *ngSwitchCase="tabName.Keymap" class="popover-content" [defaultKeyAction]="defaultKeyAction" [keymaps]="keymaps$ | async"></keymap-tab>
|
||||
<none-tab #tab *ngSwitchCase="tabName.None" class="popover-content"></none-tab>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="popover-action">
|
||||
|
||||
@@ -1,11 +1,66 @@
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: none;
|
||||
padding: 0;
|
||||
max-width: 568px;
|
||||
width: 100%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
> .container-fluid {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&.leftArrow {
|
||||
transform: none;
|
||||
|
||||
.arrowCustom {
|
||||
transform: none;
|
||||
left: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
&.rightArrow {
|
||||
transform: none;
|
||||
|
||||
.arrowCustom {
|
||||
transform: none;
|
||||
right: 22px;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.arrowCustom {
|
||||
position: absolute;
|
||||
top: -16px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
top: 100px;
|
||||
width: 41px;
|
||||
height: 16px;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 21px solid transparent;
|
||||
border-right: 21px solid transparent;
|
||||
border-bottom: 17px solid rgba(0, 0, 0, 0.2);
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 20px solid transparent;
|
||||
border-right: 20px solid transparent;
|
||||
border-bottom: 16px solid #f7f7f7;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.popover-action {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import {
|
||||
Component, ElementRef, EventEmitter, HostBinding, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild
|
||||
} from '@angular/core';
|
||||
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
@@ -33,23 +35,30 @@ enum TabName {
|
||||
styles: [require('./popover.component.scss')],
|
||||
host: { 'class': 'popover' }
|
||||
})
|
||||
export class PopoverComponent implements OnInit {
|
||||
export class PopoverComponent implements OnInit, OnChanges {
|
||||
@Input() defaultKeyAction: KeyAction;
|
||||
@Input() currentKeymap: Keymap;
|
||||
@Input() keyPosition: ClientRect;
|
||||
@Input() wrapPosition: ClientRect;
|
||||
|
||||
@Output() cancel = new EventEmitter<any>();
|
||||
@Output() remap = new EventEmitter<KeyAction>();
|
||||
|
||||
@ViewChild('tab') selectedTab: Tab;
|
||||
|
||||
/* tslint:disable:variable-name: It is an enum type. So it can start with uppercase. */
|
||||
/* tslint:disable:no-unused-variable: It is used in the template. */
|
||||
private TabName = TabName;
|
||||
/* tslint:enable:no-unused-variable tslint:enable:variable-name */
|
||||
@HostBinding('style.top.px') topPosition: number;
|
||||
@HostBinding('style.left.px') leftPosition: number;
|
||||
@HostBinding('class.leftArrow') leftArrow: boolean = false;
|
||||
@HostBinding('class.rightArrow') rightArrow: boolean = false;
|
||||
|
||||
public tabName = TabName;
|
||||
private activeTab: TabName;
|
||||
private keymaps$: Observable<Keymap[]>;
|
||||
private popoverHost: HTMLElement;
|
||||
|
||||
constructor(private store: Store<AppState>, private element: ElementRef) {
|
||||
this.popoverHost = element.nativeElement;
|
||||
|
||||
constructor(private store: Store<AppState>) {
|
||||
this.keymaps$ = store.let(getKeymapEntities())
|
||||
.map((keymaps: Keymap[]) =>
|
||||
keymaps.filter((keymap: Keymap) => this.currentKeymap.abbreviation !== keymap.abbreviation)
|
||||
@@ -76,6 +85,12 @@ export class PopoverComponent implements OnInit {
|
||||
this.selectTab(tab);
|
||||
}
|
||||
|
||||
ngOnChanges(change: SimpleChanges) {
|
||||
if (change['keyPosition'] || change['wrapPosition']) {
|
||||
this.calculatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
onCancelClick(): void {
|
||||
this.cancel.emit(undefined);
|
||||
}
|
||||
@@ -93,4 +108,21 @@ export class PopoverComponent implements OnInit {
|
||||
selectTab(tab: TabName): void {
|
||||
this.activeTab = tab;
|
||||
}
|
||||
|
||||
private calculatePosition() {
|
||||
const offsetLeft: number = this.wrapPosition.left + 265;
|
||||
let newLeft: number = this.keyPosition.left + (this.keyPosition.width / 2);
|
||||
|
||||
this.leftArrow = newLeft < offsetLeft;
|
||||
this.rightArrow = (newLeft + this.popoverHost.offsetWidth) > offsetLeft + this.wrapPosition.width;
|
||||
|
||||
if (this.leftArrow) {
|
||||
newLeft = this.keyPosition.left;
|
||||
} else if (this.rightArrow) {
|
||||
newLeft = this.keyPosition.left - this.popoverHost.offsetWidth + this.keyPosition.width;
|
||||
}
|
||||
|
||||
this.topPosition = this.keyPosition.top + this.keyPosition.height + 7;
|
||||
this.leftPosition = newLeft;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[keyboardKeys]="module.keyboardKeys"
|
||||
[attr.transform]="module.attributes.transform"
|
||||
[keyActions]="moduleConfig[i].keyActions"
|
||||
(keyClick)="onKeyClick(i, $event)"
|
||||
(keyClick)="onKeyClick(i, $event.index, $event.keyTarget)"
|
||||
(keyHover)="onKeyHover($event.index, $event.event, $event.over, i)"
|
||||
/>
|
||||
</svg:g>
|
||||
|
||||
|
Before Width: | Height: | Size: 653 B After Width: | Height: | Size: 677 B |
@@ -25,10 +25,11 @@ export class SvgKeyboardComponent implements OnInit {
|
||||
this.modules = this.getSvgModules();
|
||||
}
|
||||
|
||||
onKeyClick(moduleId: number, keyId: number): void {
|
||||
onKeyClick(moduleId: number, keyId: number, keyTarget: HTMLElement): void {
|
||||
this.keyClick.emit({
|
||||
moduleId,
|
||||
keyId
|
||||
keyId,
|
||||
keyTarget
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
Component, Input, OnChanges, OnDestroy, OnInit, SimpleChange,
|
||||
Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChange,
|
||||
animate, group, style, transition, trigger
|
||||
} from '@angular/core';
|
||||
|
||||
@@ -59,6 +59,7 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() height: number;
|
||||
@Input() width: number;
|
||||
@Input() keyAction: KeyAction;
|
||||
@Output() keyClick = new EventEmitter();
|
||||
|
||||
enumLabelTypes = LabelTypes;
|
||||
|
||||
@@ -68,7 +69,11 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private subscription: Subscription;
|
||||
private animation: string = 'inactive';
|
||||
|
||||
constructor(private mapper: MapperService, private store: Store<AppState>) {
|
||||
@HostListener('click') onClick() {
|
||||
this.keyClick.emit(this.element.nativeElement);
|
||||
}
|
||||
|
||||
constructor(private mapper: MapperService, private store: Store<AppState>, private element: ElementRef) {
|
||||
this.subscription = store.let(getMacroEntities())
|
||||
.subscribe((macros: Macro[]) => this.macros = macros);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<svg:path *ngFor="let path of coverages" [attr.d]="path.$.d"/>
|
||||
<svg:path *ngFor="let path of coverages" [attr.d]="path.$.d" />
|
||||
<svg:g svg-keyboard-key *ngFor="let key of keyboardKeys; let i = index"
|
||||
[id]="key.id"
|
||||
[rx]="key.rx" [ry]="key.ry"
|
||||
[width]="key.width" [height]="key.height"
|
||||
[attr.transform]="'translate(' + key.x + ' ' + key.y + ')'"
|
||||
[keyAction]="keyActions[i]"
|
||||
(click)="onKeyClick(i)"
|
||||
(keyClick)="onKeyClick(i, $event)"
|
||||
(mouseenter)="onKeyHover(i, $event, true)"
|
||||
(mouseleave)="onKeyHover(i, $event, false)"
|
||||
/>
|
||||
|
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 496 B |
@@ -13,15 +13,18 @@ export class SvgModuleComponent {
|
||||
@Input() coverages: any[];
|
||||
@Input() keyboardKeys: SvgKeyboardKey[];
|
||||
@Input() keyActions: KeyAction[];
|
||||
@Output() keyClick = new EventEmitter<number>();
|
||||
@Output() keyClick = new EventEmitter();
|
||||
@Output() keyHover = new EventEmitter();
|
||||
|
||||
constructor() {
|
||||
this.keyboardKeys = [];
|
||||
}
|
||||
|
||||
onKeyClick(index: number): void {
|
||||
this.keyClick.emit(index);
|
||||
onKeyClick(index: number, keyTarget: HTMLElement): void {
|
||||
this.keyClick.emit({
|
||||
index,
|
||||
keyTarget
|
||||
});
|
||||
}
|
||||
|
||||
onKeyHover(index: number, event: MouseEvent, over: boolean): void {
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<svg-keyboard *ngFor="let layer of layers; trackBy: trackKeyboard"
|
||||
[@layerState]="layer.animation"
|
||||
[moduleConfig]="layer.modules"
|
||||
(keyClick)="onKeyClick($event.moduleId, $event.keyId)"
|
||||
(keyClick)="onKeyClick($event.moduleId, $event.keyId, $event.keyTarget)"
|
||||
(keyHover)="onKeyHover($event.moduleId, $event.event, $event.over, $event.keyId)"
|
||||
>
|
||||
</svg-keyboard>
|
||||
</div>
|
||||
<popover *ngIf="popoverShown" [defaultKeyAction]="popoverInitKeyAction" [currentKeymap]="keymap" (cancel)="hidePopover()" (remap)="onRemap($event)"></popover>
|
||||
<popover *ngIf="popoverShown" [keyPosition]="keyPosition" [wrapPosition]="wrapPosition" [defaultKeyAction]="popoverInitKeyAction" [currentKeymap]="keymap" (cancel)="hidePopover()" (remap)="onRemap($event)"></popover>
|
||||
<div class="tooltip bottom"
|
||||
[class.in]="tooltipData.show"
|
||||
[style.top.px]="tooltipData.posTop"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
SimpleChanges,
|
||||
animate,
|
||||
keyframes,
|
||||
@@ -88,7 +91,7 @@ import { KeymapActions } from '../../../store/actions';
|
||||
])
|
||||
]
|
||||
})
|
||||
export class SvgKeyboardWrapComponent implements OnChanges {
|
||||
export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
|
||||
@Input() keymap: Keymap;
|
||||
@Input() popoverEnabled: boolean = true;
|
||||
@Input() tooltipEnabled: boolean = false;
|
||||
@@ -99,8 +102,18 @@ export class SvgKeyboardWrapComponent implements OnChanges {
|
||||
private currentLayer: number = 0;
|
||||
private tooltipData: { posTop: number, posLeft: number, content: { name: string, value: string }[], show: boolean };
|
||||
private layers: Layer[];
|
||||
private keyPosition: ClientRect;
|
||||
private wrapPosition: ClientRect;
|
||||
private wrapHost: HTMLElement;
|
||||
private keyElement: HTMLElement;
|
||||
|
||||
constructor(private store: Store<AppState>, private mapper: MapperService) {
|
||||
@HostListener('window:resize')
|
||||
onClick() {
|
||||
this.wrapPosition = this.wrapHost.getBoundingClientRect();
|
||||
this.keyPosition = this.keyElement.getBoundingClientRect();
|
||||
}
|
||||
|
||||
constructor(private store: Store<AppState>, private mapper: MapperService, private element: ElementRef) {
|
||||
this.keyEditConfig = {
|
||||
moduleId: undefined,
|
||||
keyId: undefined
|
||||
@@ -114,6 +127,11 @@ export class SvgKeyboardWrapComponent implements OnChanges {
|
||||
};
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.wrapHost = this.element.nativeElement;
|
||||
this.wrapPosition = this.wrapHost.getBoundingClientRect();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['keymap'].previousValue.abbreviation !== changes['keymap'].currentValue.abbreviation) {
|
||||
this.layers = this.keymap.layers;
|
||||
@@ -129,7 +147,7 @@ export class SvgKeyboardWrapComponent implements OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
onKeyClick(moduleId: number, keyId: number): void {
|
||||
onKeyClick(moduleId: number, keyId: number, keyTarget: HTMLElement): void {
|
||||
if (!this.popoverShown && this.popoverEnabled) {
|
||||
this.keyEditConfig = {
|
||||
moduleId,
|
||||
@@ -137,6 +155,7 @@ export class SvgKeyboardWrapComponent implements OnChanges {
|
||||
};
|
||||
|
||||
const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[moduleId].keyActions[keyId];
|
||||
this.keyElement = keyTarget;
|
||||
this.showPopover(keyActionToEdit);
|
||||
}
|
||||
}
|
||||
@@ -165,7 +184,8 @@ export class SvgKeyboardWrapComponent implements OnChanges {
|
||||
this.hidePopover();
|
||||
}
|
||||
|
||||
showPopover(keyAction?: KeyAction): void {
|
||||
showPopover(keyAction: KeyAction): void {
|
||||
this.keyPosition = this.keyElement.getBoundingClientRect();
|
||||
this.popoverInitKeyAction = keyAction;
|
||||
this.popoverShown = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user