verticalResizablePanes.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. let newSize = defaultSize ?? 'auto'
  67. if (open) {
  68. if (storedSize) {
  69. newSize = storedSize
  70. }
  71. enableResizer()
  72. } else {
  73. disableResizer()
  74. }
  75. layoutHandle.sizePane('south', newSize)
  76. })
  77. }
  78. if (hiddenExternally) {
  79. ide.$scope.$on(hiddenExternally, (e, open) => {
  80. if (open) {
  81. layoutHandle.show('south')
  82. } else {
  83. layoutHandle.hide('south')
  84. }
  85. })
  86. }
  87. if (resizeOn) {
  88. ide.$scope.$on(resizeOn, () => {
  89. ide.$timeout(() => {
  90. layoutHandle.resizeAll()
  91. })
  92. })
  93. }
  94. if (maxSize) {
  95. layoutOptions.south.maxSize = maxSize
  96. }
  97. if (minSize) {
  98. layoutOptions.south.minSize = minSize
  99. }
  100. if (defaultSize) {
  101. layoutOptions.south.size = defaultSize
  102. }
  103. // The `drag` event fires only when the user manually resizes the panes; the `resize` event fires even when
  104. // the layout library internally resizes itself. In order to get explicit user-initiated resizes, we need to
  105. // listen to `drag` events. However, when the `drag` event fires, the panes aren't yet finished sizing so we
  106. // get the pane size *before* the resize happens. We do get the correct size in the next `resize` event.
  107. // The solution to work around this is to set up a flag in `drag` events which tells the next `resize` event
  108. // that it was user-initiated (therefore, storing the value).
  109. layoutOptions.south.ondrag_end = handleDragEnd
  110. layoutOptions.south.onresize = handleResize
  111. const layoutHandle = element.layout(layoutOptions)
  112. if (hiddenInitially === 'true') {
  113. layoutHandle.hide('south')
  114. }
  115. },
  116. }))