2cae052d4d8e7c7196a1d0e294c540beda04758eee32706c1e9bacd220fdbdf5f93954d44ee6e3f95f5a9776f6c4cac901c264d9d58b8543ff04270641ec89 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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 './glyphMargin.css';
  6. import { DynamicViewOverlay } from '../../view/dynamicViewOverlay.js';
  7. export class DecorationToRender {
  8. constructor(startLineNumber, endLineNumber, className) {
  9. this._decorationToRenderBrand = undefined;
  10. this.startLineNumber = +startLineNumber;
  11. this.endLineNumber = +endLineNumber;
  12. this.className = String(className);
  13. }
  14. }
  15. export class DedupOverlay extends DynamicViewOverlay {
  16. _render(visibleStartLineNumber, visibleEndLineNumber, decorations) {
  17. const output = [];
  18. for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) {
  19. const lineIndex = lineNumber - visibleStartLineNumber;
  20. output[lineIndex] = [];
  21. }
  22. if (decorations.length === 0) {
  23. return output;
  24. }
  25. decorations.sort((a, b) => {
  26. if (a.className === b.className) {
  27. if (a.startLineNumber === b.startLineNumber) {
  28. return a.endLineNumber - b.endLineNumber;
  29. }
  30. return a.startLineNumber - b.startLineNumber;
  31. }
  32. return (a.className < b.className ? -1 : 1);
  33. });
  34. let prevClassName = null;
  35. let prevEndLineIndex = 0;
  36. for (let i = 0, len = decorations.length; i < len; i++) {
  37. const d = decorations[i];
  38. const className = d.className;
  39. let startLineIndex = Math.max(d.startLineNumber, visibleStartLineNumber) - visibleStartLineNumber;
  40. const endLineIndex = Math.min(d.endLineNumber, visibleEndLineNumber) - visibleStartLineNumber;
  41. if (prevClassName === className) {
  42. startLineIndex = Math.max(prevEndLineIndex + 1, startLineIndex);
  43. prevEndLineIndex = Math.max(prevEndLineIndex, endLineIndex);
  44. }
  45. else {
  46. prevClassName = className;
  47. prevEndLineIndex = endLineIndex;
  48. }
  49. for (let i = startLineIndex; i <= prevEndLineIndex; i++) {
  50. output[i].push(prevClassName);
  51. }
  52. }
  53. return output;
  54. }
  55. }
  56. export class GlyphMarginOverlay extends DedupOverlay {
  57. constructor(context) {
  58. super();
  59. this._context = context;
  60. const options = this._context.configuration.options;
  61. const layoutInfo = options.get(133 /* EditorOption.layoutInfo */);
  62. this._lineHeight = options.get(61 /* EditorOption.lineHeight */);
  63. this._glyphMargin = options.get(52 /* EditorOption.glyphMargin */);
  64. this._glyphMarginLeft = layoutInfo.glyphMarginLeft;
  65. this._glyphMarginWidth = layoutInfo.glyphMarginWidth;
  66. this._renderResult = null;
  67. this._context.addEventHandler(this);
  68. }
  69. dispose() {
  70. this._context.removeEventHandler(this);
  71. this._renderResult = null;
  72. super.dispose();
  73. }
  74. // --- begin event handlers
  75. onConfigurationChanged(e) {
  76. const options = this._context.configuration.options;
  77. const layoutInfo = options.get(133 /* EditorOption.layoutInfo */);
  78. this._lineHeight = options.get(61 /* EditorOption.lineHeight */);
  79. this._glyphMargin = options.get(52 /* EditorOption.glyphMargin */);
  80. this._glyphMarginLeft = layoutInfo.glyphMarginLeft;
  81. this._glyphMarginWidth = layoutInfo.glyphMarginWidth;
  82. return true;
  83. }
  84. onDecorationsChanged(e) {
  85. return true;
  86. }
  87. onFlushed(e) {
  88. return true;
  89. }
  90. onLinesChanged(e) {
  91. return true;
  92. }
  93. onLinesDeleted(e) {
  94. return true;
  95. }
  96. onLinesInserted(e) {
  97. return true;
  98. }
  99. onScrollChanged(e) {
  100. return e.scrollTopChanged;
  101. }
  102. onZonesChanged(e) {
  103. return true;
  104. }
  105. // --- end event handlers
  106. _getDecorations(ctx) {
  107. const decorations = ctx.getDecorationsInViewport();
  108. const r = [];
  109. let rLen = 0;
  110. for (let i = 0, len = decorations.length; i < len; i++) {
  111. const d = decorations[i];
  112. const glyphMarginClassName = d.options.glyphMarginClassName;
  113. if (glyphMarginClassName) {
  114. r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, glyphMarginClassName);
  115. }
  116. }
  117. return r;
  118. }
  119. prepareRender(ctx) {
  120. if (!this._glyphMargin) {
  121. this._renderResult = null;
  122. return;
  123. }
  124. const visibleStartLineNumber = ctx.visibleRange.startLineNumber;
  125. const visibleEndLineNumber = ctx.visibleRange.endLineNumber;
  126. const toRender = this._render(visibleStartLineNumber, visibleEndLineNumber, this._getDecorations(ctx));
  127. const lineHeight = this._lineHeight.toString();
  128. const left = this._glyphMarginLeft.toString();
  129. const width = this._glyphMarginWidth.toString();
  130. const common = '" style="left:' + left + 'px;width:' + width + 'px' + ';height:' + lineHeight + 'px;"></div>';
  131. const output = [];
  132. for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) {
  133. const lineIndex = lineNumber - visibleStartLineNumber;
  134. const classNames = toRender[lineIndex];
  135. if (classNames.length === 0) {
  136. output[lineIndex] = '';
  137. }
  138. else {
  139. output[lineIndex] = ('<div class="cgmr codicon '
  140. + classNames.join(' ')
  141. + common);
  142. }
  143. }
  144. this._renderResult = output;
  145. }
  146. render(startLineNumber, lineNumber) {
  147. if (!this._renderResult) {
  148. return '';
  149. }
  150. const lineIndex = lineNumber - startLineNumber;
  151. if (lineIndex < 0 || lineIndex >= this._renderResult.length) {
  152. return '';
  153. }
  154. return this._renderResult[lineIndex];
  155. }
  156. }