overviewZoneManager.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. export class ColorZone {
  6. constructor(from, to, colorId) {
  7. this._colorZoneBrand = undefined;
  8. this.from = from | 0;
  9. this.to = to | 0;
  10. this.colorId = colorId | 0;
  11. }
  12. static compare(a, b) {
  13. if (a.colorId === b.colorId) {
  14. if (a.from === b.from) {
  15. return a.to - b.to;
  16. }
  17. return a.from - b.from;
  18. }
  19. return a.colorId - b.colorId;
  20. }
  21. }
  22. /**
  23. * A zone in the overview ruler
  24. */
  25. export class OverviewRulerZone {
  26. constructor(startLineNumber, endLineNumber, color) {
  27. this._overviewRulerZoneBrand = undefined;
  28. this.startLineNumber = startLineNumber;
  29. this.endLineNumber = endLineNumber;
  30. this.color = color;
  31. this._colorZone = null;
  32. }
  33. static compare(a, b) {
  34. if (a.color === b.color) {
  35. if (a.startLineNumber === b.startLineNumber) {
  36. return a.endLineNumber - b.endLineNumber;
  37. }
  38. return a.startLineNumber - b.startLineNumber;
  39. }
  40. return a.color < b.color ? -1 : 1;
  41. }
  42. setColorZone(colorZone) {
  43. this._colorZone = colorZone;
  44. }
  45. getColorZones() {
  46. return this._colorZone;
  47. }
  48. }
  49. export class OverviewZoneManager {
  50. constructor(getVerticalOffsetForLine) {
  51. this._getVerticalOffsetForLine = getVerticalOffsetForLine;
  52. this._zones = [];
  53. this._colorZonesInvalid = false;
  54. this._lineHeight = 0;
  55. this._domWidth = 0;
  56. this._domHeight = 0;
  57. this._outerHeight = 0;
  58. this._pixelRatio = 1;
  59. this._lastAssignedId = 0;
  60. this._color2Id = Object.create(null);
  61. this._id2Color = [];
  62. }
  63. getId2Color() {
  64. return this._id2Color;
  65. }
  66. setZones(newZones) {
  67. this._zones = newZones;
  68. this._zones.sort(OverviewRulerZone.compare);
  69. }
  70. setLineHeight(lineHeight) {
  71. if (this._lineHeight === lineHeight) {
  72. return false;
  73. }
  74. this._lineHeight = lineHeight;
  75. this._colorZonesInvalid = true;
  76. return true;
  77. }
  78. setPixelRatio(pixelRatio) {
  79. this._pixelRatio = pixelRatio;
  80. this._colorZonesInvalid = true;
  81. }
  82. getDOMWidth() {
  83. return this._domWidth;
  84. }
  85. getCanvasWidth() {
  86. return this._domWidth * this._pixelRatio;
  87. }
  88. setDOMWidth(width) {
  89. if (this._domWidth === width) {
  90. return false;
  91. }
  92. this._domWidth = width;
  93. this._colorZonesInvalid = true;
  94. return true;
  95. }
  96. getDOMHeight() {
  97. return this._domHeight;
  98. }
  99. getCanvasHeight() {
  100. return this._domHeight * this._pixelRatio;
  101. }
  102. setDOMHeight(height) {
  103. if (this._domHeight === height) {
  104. return false;
  105. }
  106. this._domHeight = height;
  107. this._colorZonesInvalid = true;
  108. return true;
  109. }
  110. getOuterHeight() {
  111. return this._outerHeight;
  112. }
  113. setOuterHeight(outerHeight) {
  114. if (this._outerHeight === outerHeight) {
  115. return false;
  116. }
  117. this._outerHeight = outerHeight;
  118. this._colorZonesInvalid = true;
  119. return true;
  120. }
  121. resolveColorZones() {
  122. const colorZonesInvalid = this._colorZonesInvalid;
  123. const lineHeight = Math.floor(this._lineHeight);
  124. const totalHeight = Math.floor(this.getCanvasHeight());
  125. const outerHeight = Math.floor(this._outerHeight);
  126. const heightRatio = totalHeight / outerHeight;
  127. const halfMinimumHeight = Math.floor(4 /* MINIMUM_HEIGHT */ * this._pixelRatio / 2);
  128. let allColorZones = [];
  129. for (let i = 0, len = this._zones.length; i < len; i++) {
  130. const zone = this._zones[i];
  131. if (!colorZonesInvalid) {
  132. const colorZone = zone.getColorZones();
  133. if (colorZone) {
  134. allColorZones.push(colorZone);
  135. continue;
  136. }
  137. }
  138. const y1 = Math.floor(heightRatio * (this._getVerticalOffsetForLine(zone.startLineNumber)));
  139. const y2 = Math.floor(heightRatio * (this._getVerticalOffsetForLine(zone.endLineNumber) + lineHeight));
  140. let ycenter = Math.floor((y1 + y2) / 2);
  141. let halfHeight = (y2 - ycenter);
  142. if (halfHeight < halfMinimumHeight) {
  143. halfHeight = halfMinimumHeight;
  144. }
  145. if (ycenter - halfHeight < 0) {
  146. ycenter = halfHeight;
  147. }
  148. if (ycenter + halfHeight > totalHeight) {
  149. ycenter = totalHeight - halfHeight;
  150. }
  151. const color = zone.color;
  152. let colorId = this._color2Id[color];
  153. if (!colorId) {
  154. colorId = (++this._lastAssignedId);
  155. this._color2Id[color] = colorId;
  156. this._id2Color[colorId] = color;
  157. }
  158. const colorZone = new ColorZone(ycenter - halfHeight, ycenter + halfHeight, colorId);
  159. zone.setColorZone(colorZone);
  160. allColorZones.push(colorZone);
  161. }
  162. this._colorZonesInvalid = false;
  163. allColorZones.sort(ColorZone.compare);
  164. return allColorZones;
  165. }
  166. }