From 97b7f8008b4825c9ef276eeb675a679043cb64ec Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Fri, 25 Nov 2016 22:11:08 +0100 Subject: [PATCH] Added positioning to the popover --- .../keymap/edit/keymap-edit.component.scss | 1 - src/components/popover/popover.component.html | 25 ++++---- src/components/popover/popover.component.scss | 59 ++++++++++++++++++- src/components/popover/popover.component.ts | 46 ++++++++++++--- .../svg/keyboard/svg-keyboard.component.html | 2 +- .../svg/keyboard/svg-keyboard.component.ts | 5 +- .../svg-keyboard-key.component.ts | 9 ++- .../svg/module/svg-module.component.html | 4 +- .../svg/module/svg-module.component.ts | 9 ++- .../svg/wrap/svg-keyboard-wrap.component.html | 4 +- .../svg/wrap/svg-keyboard-wrap.component.scss | 2 - .../svg/wrap/svg-keyboard-wrap.component.ts | 28 +++++++-- 12 files changed, 154 insertions(+), 40 deletions(-) diff --git a/src/components/keymap/edit/keymap-edit.component.scss b/src/components/keymap/edit/keymap-edit.component.scss index 529694f2..de664322 100644 --- a/src/components/keymap/edit/keymap-edit.component.scss +++ b/src/components/keymap/edit/keymap-edit.component.scss @@ -1,6 +1,5 @@ :host { width: 100%; - height: 100%; display: block; } diff --git a/src/components/popover/popover.component.html b/src/components/popover/popover.component.html index 66cd9378..a63dcc87 100644 --- a/src/components/popover/popover.component.html +++ b/src/components/popover/popover.component.html @@ -1,38 +1,39 @@ +
- - - - - - + + + + + +
diff --git a/src/components/popover/popover.component.scss b/src/components/popover/popover.component.scss index befdf1dd..ff0ea9d0 100644 --- a/src/components/popover/popover.component.scss +++ b/src/components/popover/popover.component.scss @@ -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 { diff --git a/src/components/popover/popover.component.ts b/src/components/popover/popover.component.ts index ee4118eb..3116b9ea 100644 --- a/src/components/popover/popover.component.ts +++ b/src/components/popover/popover.component.ts @@ -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(); @Output() remap = new EventEmitter(); @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; + private popoverHost: HTMLElement; + + constructor(private store: Store, private element: ElementRef) { + this.popoverHost = element.nativeElement; - constructor(private store: Store) { 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; + } } diff --git a/src/components/svg/keyboard/svg-keyboard.component.html b/src/components/svg/keyboard/svg-keyboard.component.html index 7d7d3841..1b97ba19 100644 --- a/src/components/svg/keyboard/svg-keyboard.component.html +++ b/src/components/svg/keyboard/svg-keyboard.component.html @@ -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)" /> diff --git a/src/components/svg/keyboard/svg-keyboard.component.ts b/src/components/svg/keyboard/svg-keyboard.component.ts index b0e3fe33..0f3c8ca2 100644 --- a/src/components/svg/keyboard/svg-keyboard.component.ts +++ b/src/components/svg/keyboard/svg-keyboard.component.ts @@ -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 }); } diff --git a/src/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts b/src/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts index bfe7e97e..b6917597 100644 --- a/src/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts +++ b/src/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts @@ -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) { + @HostListener('click') onClick() { + this.keyClick.emit(this.element.nativeElement); + } + + constructor(private mapper: MapperService, private store: Store, private element: ElementRef) { this.subscription = store.let(getMacroEntities()) .subscribe((macros: Macro[]) => this.macros = macros); } diff --git a/src/components/svg/module/svg-module.component.html b/src/components/svg/module/svg-module.component.html index 1d61ad92..ebd314dd 100644 --- a/src/components/svg/module/svg-module.component.html +++ b/src/components/svg/module/svg-module.component.html @@ -1,11 +1,11 @@ - + \ No newline at end of file diff --git a/src/components/svg/module/svg-module.component.ts b/src/components/svg/module/svg-module.component.ts index 7b3e7f7b..d376f163 100644 --- a/src/components/svg/module/svg-module.component.ts +++ b/src/components/svg/module/svg-module.component.ts @@ -13,15 +13,18 @@ export class SvgModuleComponent { @Input() coverages: any[]; @Input() keyboardKeys: SvgKeyboardKey[]; @Input() keyActions: KeyAction[]; - @Output() keyClick = new EventEmitter(); + @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 { diff --git a/src/components/svg/wrap/svg-keyboard-wrap.component.html b/src/components/svg/wrap/svg-keyboard-wrap.component.html index 686f9b9c..658c6003 100644 --- a/src/components/svg/wrap/svg-keyboard-wrap.component.html +++ b/src/components/svg/wrap/svg-keyboard-wrap.component.html @@ -4,12 +4,12 @@
- +
, private mapper: MapperService) { + @HostListener('window:resize') + onClick() { + this.wrapPosition = this.wrapHost.getBoundingClientRect(); + this.keyPosition = this.keyElement.getBoundingClientRect(); + } + + constructor(private store: Store, 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; }