splitTabSpanner.component.ts 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
  2. import { Component, Input, HostBinding, ElementRef, Output, EventEmitter } from '@angular/core'
  3. import { SelfPositioningComponent } from './selfPositioning.component'
  4. import { SplitContainer } from './splitTab.component'
  5. /** @hidden */
  6. @Component({
  7. selector: 'split-tab-spanner',
  8. template: '',
  9. styleUrls: ['./splitTabSpanner.component.scss'],
  10. })
  11. export class SplitTabSpannerComponent extends SelfPositioningComponent {
  12. @Input() container: SplitContainer
  13. @Input() index: number
  14. @Output() resizing = new EventEmitter<boolean>()
  15. @Output() change = new EventEmitter<void>()
  16. @HostBinding('class.active') isActive = false
  17. @HostBinding('class.h') isHorizontal = false
  18. @HostBinding('class.v') isVertical = true
  19. private marginOffset = -5
  20. // eslint-disable-next-line @typescript-eslint/no-useless-constructor
  21. constructor (element: ElementRef) {
  22. super(element)
  23. }
  24. ngAfterViewInit () {
  25. this.element.nativeElement.addEventListener('dblclick', () => {
  26. this.reset()
  27. })
  28. this.element.nativeElement.addEventListener('mousedown', (e: MouseEvent) => {
  29. this.isActive = true
  30. this.resizing.emit(true)
  31. const start = this.isVertical ? e.pageY : e.pageX
  32. let current = start
  33. const oldPosition: number = this.isVertical ? this.element.nativeElement.offsetTop : this.element.nativeElement.offsetLeft
  34. const dragHandler = (dragEvent: MouseEvent) => {
  35. current = this.isVertical ? dragEvent.pageY : dragEvent.pageX
  36. const newPosition = oldPosition + (current - start)
  37. if (this.isVertical) {
  38. this.element.nativeElement.style.top = `${newPosition - this.marginOffset}px`
  39. } else {
  40. this.element.nativeElement.style.left = `${newPosition - this.marginOffset}px`
  41. }
  42. }
  43. const offHandler = () => {
  44. this.isActive = false
  45. this.resizing.emit(false)
  46. document.removeEventListener('mouseup', offHandler)
  47. this.element.nativeElement.parentElement.removeEventListener('mousemove', dragHandler)
  48. let diff = (current - start) / (this.isVertical ? this.element.nativeElement.parentElement.clientHeight : this.element.nativeElement.parentElement.clientWidth)
  49. diff = Math.max(diff, -this.container.ratios[this.index - 1] + 0.1)
  50. diff = Math.min(diff, this.container.ratios[this.index] - 0.1)
  51. if (diff) {
  52. this.container.ratios[this.index - 1] += diff
  53. this.container.ratios[this.index] -= diff
  54. this.change.emit()
  55. }
  56. }
  57. document.addEventListener('mouseup', offHandler, { passive: true })
  58. this.element.nativeElement.parentElement.addEventListener('mousemove', dragHandler)
  59. }, { passive: true })
  60. }
  61. ngOnChanges () {
  62. this.isHorizontal = this.container.orientation === 'h'
  63. this.isVertical = this.container.orientation === 'v'
  64. if (this.isVertical) {
  65. this.setDimensions(
  66. this.container.x,
  67. this.container.y + this.container.h * this.container.getOffsetRatio(this.index),
  68. this.container.w,
  69. 0,
  70. )
  71. } else {
  72. this.setDimensions(
  73. this.container.x + this.container.w * this.container.getOffsetRatio(this.index),
  74. this.container.y,
  75. 0,
  76. this.container.h,
  77. )
  78. }
  79. }
  80. reset () {
  81. const ratio = (this.container.ratios[this.index - 1] + this.container.ratios[this.index]) / 2
  82. this.container.ratios[this.index - 1] = ratio
  83. this.container.ratios[this.index] = ratio
  84. this.change.emit()
  85. }
  86. }