verticalResizablePanes.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import App from '../../base'
  2. export default App.directive('verticalResizablePanes', (localStorage, ide) => ({
  3. restrict: 'A',
  4. link(scope, element, attrs) {
  5. const name = attrs.verticalResizablePanes
  6. const minSize = scope.$eval(attrs.verticalResizablePanesMinSize)
  7. const maxSize = scope.$eval(attrs.verticalResizablePanesMaxSize)
  8. const defaultSize = scope.$eval(attrs.verticalResizablePanesDefaultSize)
  9. let storedSize = null
  10. let manualResizeIncoming = false
  11. if (name) {
  12. const storageKey = `vertical-resizable:${name}:south-size`
  13. storedSize = localStorage(storageKey)
  14. $(window).unload(() => {
  15. if (storedSize) {
  16. localStorage(storageKey, storedSize)
  17. }
  18. })
  19. }
  20. const layoutOptions = {
  21. center: {
  22. paneSelector: '[vertical-resizable-top]',
  23. paneClass: 'vertical-resizable-top',
  24. size: 'auto',
  25. },
  26. south: {
  27. paneSelector: '[vertical-resizable-bottom]',
  28. paneClass: 'vertical-resizable-bottom',
  29. resizerClass: 'vertical-resizable-resizer',
  30. resizerCursor: 'ns-resize',
  31. size: 'auto',
  32. resizable: true,
  33. closable: false,
  34. slidable: false,
  35. spacing_open: 6,
  36. spacing_closed: 6,
  37. maxSize: '75%',
  38. },
  39. }
  40. const toggledExternally = attrs.verticalResizablePanesToggledExternallyOn
  41. const hiddenExternally = attrs.verticalResizablePanesHiddenExternallyOn
  42. const hiddenInitially = attrs.verticalResizablePanesHiddenInitially
  43. const resizeOn = attrs.verticalResizablePanesResizeOn
  44. const resizerDisabledClass = `${layoutOptions.south.resizerClass}-disabled`
  45. function enableResizer() {
  46. if (layoutHandle.resizers && layoutHandle.resizers.south) {
  47. layoutHandle.resizers.south.removeClass(resizerDisabledClass)
  48. }
  49. }
  50. function disableResizer() {
  51. if (layoutHandle.resizers && layoutHandle.resizers.south) {
  52. layoutHandle.resizers.south.addClass(resizerDisabledClass)
  53. }
  54. }
  55. function handleDragEnd() {
  56. manualResizeIncoming = true
  57. }
  58. function handleResize(paneName, paneEl, paneState) {
  59. if (manualResizeIncoming) {
  60. storedSize = paneState.size
  61. }
  62. manualResizeIncoming = false
  63. }
  64. if (toggledExternally) {
  65. scope.$on(toggledExternally, (e, open) => {
  66. if (open) {
  67. enableResizer()
  68. layoutHandle.sizePane('south', storedSize ?? defaultSize ?? 'auto')
  69. } else {
  70. disableResizer()
  71. layoutHandle.sizePane('south', 'auto')
  72. }
  73. })
  74. }
  75. if (hiddenExternally) {
  76. ide.$scope.$on(hiddenExternally, (e, open) => {
  77. if (open) {
  78. layoutHandle.show('south')
  79. } else {
  80. layoutHandle.hide('south')
  81. }
  82. })
  83. }
  84. if (resizeOn) {
  85. ide.$scope.$on(resizeOn, () => {
  86. ide.$timeout(() => {
  87. layoutHandle.resizeAll()
  88. })
  89. })
  90. }
  91. if (maxSize) {
  92. layoutOptions.south.maxSize = maxSize
  93. }
  94. if (minSize) {
  95. layoutOptions.south.minSize = minSize
  96. }
  97. if (defaultSize) {
  98. layoutOptions.south.size = defaultSize
  99. }
  100. // The `drag` event fires only when the user manually resizes the panes; the `resize` event fires even when
  101. // the layout library internally resizes itself. In order to get explicit user-initiated resizes, we need to
  102. // listen to `drag` events. However, when the `drag` event fires, the panes aren't yet finished sizing so we
  103. // get the pane size *before* the resize happens. We do get the correct size in the next `resize` event.
  104. // The solution to work around this is to set up a flag in `drag` events which tells the next `resize` event
  105. // that it was user-initiated (therefore, storing the value).
  106. layoutOptions.south.ondrag_end = handleDragEnd
  107. layoutOptions.south.onresize = handleResize
  108. const layoutHandle = element.layout(layoutOptions)
  109. if (hiddenInitially === 'true') {
  110. layoutHandle.hide('south')
  111. }
  112. },
  113. }))