resizable.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { Dimension } from '../../../base/browser/dom.js';
  6. import { OrthogonalEdge, Sash } from '../../../base/browser/ui/sash/sash.js';
  7. import { Emitter, Event } from '../../../base/common/event.js';
  8. import { DisposableStore } from '../../../base/common/lifecycle.js';
  9. export class ResizableHTMLElement {
  10. constructor() {
  11. this._onDidWillResize = new Emitter();
  12. this.onDidWillResize = this._onDidWillResize.event;
  13. this._onDidResize = new Emitter();
  14. this.onDidResize = this._onDidResize.event;
  15. this._sashListener = new DisposableStore();
  16. this._size = new Dimension(0, 0);
  17. this._minSize = new Dimension(0, 0);
  18. this._maxSize = new Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
  19. this.domNode = document.createElement('div');
  20. this._eastSash = new Sash(this.domNode, { getVerticalSashLeft: () => this._size.width }, { orientation: 0 /* VERTICAL */ });
  21. this._westSash = new Sash(this.domNode, { getVerticalSashLeft: () => 0 }, { orientation: 0 /* VERTICAL */ });
  22. this._northSash = new Sash(this.domNode, { getHorizontalSashTop: () => 0 }, { orientation: 1 /* HORIZONTAL */, orthogonalEdge: OrthogonalEdge.North });
  23. this._southSash = new Sash(this.domNode, { getHorizontalSashTop: () => this._size.height }, { orientation: 1 /* HORIZONTAL */, orthogonalEdge: OrthogonalEdge.South });
  24. this._northSash.orthogonalStartSash = this._westSash;
  25. this._northSash.orthogonalEndSash = this._eastSash;
  26. this._southSash.orthogonalStartSash = this._westSash;
  27. this._southSash.orthogonalEndSash = this._eastSash;
  28. let currentSize;
  29. let deltaY = 0;
  30. let deltaX = 0;
  31. this._sashListener.add(Event.any(this._northSash.onDidStart, this._eastSash.onDidStart, this._southSash.onDidStart, this._westSash.onDidStart)(() => {
  32. if (currentSize === undefined) {
  33. this._onDidWillResize.fire();
  34. currentSize = this._size;
  35. deltaY = 0;
  36. deltaX = 0;
  37. }
  38. }));
  39. this._sashListener.add(Event.any(this._northSash.onDidEnd, this._eastSash.onDidEnd, this._southSash.onDidEnd, this._westSash.onDidEnd)(() => {
  40. if (currentSize !== undefined) {
  41. currentSize = undefined;
  42. deltaY = 0;
  43. deltaX = 0;
  44. this._onDidResize.fire({ dimension: this._size, done: true });
  45. }
  46. }));
  47. this._sashListener.add(this._eastSash.onDidChange(e => {
  48. if (currentSize) {
  49. deltaX = e.currentX - e.startX;
  50. this.layout(currentSize.height + deltaY, currentSize.width + deltaX);
  51. this._onDidResize.fire({ dimension: this._size, done: false, east: true });
  52. }
  53. }));
  54. this._sashListener.add(this._westSash.onDidChange(e => {
  55. if (currentSize) {
  56. deltaX = -(e.currentX - e.startX);
  57. this.layout(currentSize.height + deltaY, currentSize.width + deltaX);
  58. this._onDidResize.fire({ dimension: this._size, done: false, west: true });
  59. }
  60. }));
  61. this._sashListener.add(this._northSash.onDidChange(e => {
  62. if (currentSize) {
  63. deltaY = -(e.currentY - e.startY);
  64. this.layout(currentSize.height + deltaY, currentSize.width + deltaX);
  65. this._onDidResize.fire({ dimension: this._size, done: false, north: true });
  66. }
  67. }));
  68. this._sashListener.add(this._southSash.onDidChange(e => {
  69. if (currentSize) {
  70. deltaY = e.currentY - e.startY;
  71. this.layout(currentSize.height + deltaY, currentSize.width + deltaX);
  72. this._onDidResize.fire({ dimension: this._size, done: false, south: true });
  73. }
  74. }));
  75. this._sashListener.add(Event.any(this._eastSash.onDidReset, this._westSash.onDidReset)(e => {
  76. if (this._preferredSize) {
  77. this.layout(this._size.height, this._preferredSize.width);
  78. this._onDidResize.fire({ dimension: this._size, done: true });
  79. }
  80. }));
  81. this._sashListener.add(Event.any(this._northSash.onDidReset, this._southSash.onDidReset)(e => {
  82. if (this._preferredSize) {
  83. this.layout(this._preferredSize.height, this._size.width);
  84. this._onDidResize.fire({ dimension: this._size, done: true });
  85. }
  86. }));
  87. }
  88. dispose() {
  89. this._northSash.dispose();
  90. this._southSash.dispose();
  91. this._eastSash.dispose();
  92. this._westSash.dispose();
  93. this._sashListener.dispose();
  94. this._onDidResize.dispose();
  95. this._onDidWillResize.dispose();
  96. this.domNode.remove();
  97. }
  98. enableSashes(north, east, south, west) {
  99. this._northSash.state = north ? 3 /* Enabled */ : 0 /* Disabled */;
  100. this._eastSash.state = east ? 3 /* Enabled */ : 0 /* Disabled */;
  101. this._southSash.state = south ? 3 /* Enabled */ : 0 /* Disabled */;
  102. this._westSash.state = west ? 3 /* Enabled */ : 0 /* Disabled */;
  103. }
  104. layout(height = this.size.height, width = this.size.width) {
  105. const { height: minHeight, width: minWidth } = this._minSize;
  106. const { height: maxHeight, width: maxWidth } = this._maxSize;
  107. height = Math.max(minHeight, Math.min(maxHeight, height));
  108. width = Math.max(minWidth, Math.min(maxWidth, width));
  109. const newSize = new Dimension(width, height);
  110. if (!Dimension.equals(newSize, this._size)) {
  111. this.domNode.style.height = height + 'px';
  112. this.domNode.style.width = width + 'px';
  113. this._size = newSize;
  114. this._northSash.layout();
  115. this._eastSash.layout();
  116. this._southSash.layout();
  117. this._westSash.layout();
  118. }
  119. }
  120. clearSashHoverState() {
  121. this._eastSash.clearSashHoverState();
  122. this._westSash.clearSashHoverState();
  123. this._northSash.clearSashHoverState();
  124. this._southSash.clearSashHoverState();
  125. }
  126. get size() {
  127. return this._size;
  128. }
  129. set maxSize(value) {
  130. this._maxSize = value;
  131. }
  132. get maxSize() {
  133. return this._maxSize;
  134. }
  135. set minSize(value) {
  136. this._minSize = value;
  137. }
  138. get minSize() {
  139. return this._minSize;
  140. }
  141. set preferredSize(value) {
  142. this._preferredSize = value;
  143. }
  144. get preferredSize() {
  145. return this._preferredSize;
  146. }
  147. }