Skip to content

Commit

Permalink
ScrollMap: Improve painting; reduce frequency minimap generation
Browse files Browse the repository at this point in the history
  • Loading branch information
sedwards2009 committed Dec 22, 2024
1 parent 384341c commit db170e8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
1 change: 1 addition & 0 deletions extensions/ScrollMap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"eslint": "8.53.0",
"eslint-config-extraterm": "1.0.0",
"eslint-plugin-unicorn": "42.0.0",
"extraterm-timeoutqt": "1.0.0",
"qt-construct": "0.1.0",
"shx": "^0.3.2",
"typescript": "5.2.2"
Expand Down
52 changes: 41 additions & 11 deletions extensions/ScrollMap/src/ScrollMapExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { mat2d } from "gl-matrix";

import { Block, BlockPosture, ExtensionContext, LineRangeChange, Logger, Screen, ScreenWithCursor, Terminal, TerminalBorderWidget,
TerminalOutputDetails, TerminalOutputType } from "@extraterm/extraterm-extension-api";
import { DebouncedDoLater } from "extraterm-timeoutqt";
import { QBrush, QColor, QImage, QImageFormat, QMouseEvent, QPainter, QPainterPath, QPaintEvent, QPen, QWidget, RenderHint,
WidgetEventTypes } from '@nodegui/nodegui';

Expand All @@ -23,6 +24,8 @@ const SCREEN_BORDER_WIDTH = 4;
const SCROLLBAR_WIDTH = SCROLLMAP_WIDTH_CELLS + LEFT_PADDING + RIGHT_PADDING + 2 * FRAME_WIDTH;

const ZOOM_FACTOR = 16;
const REPAINT_DELAY_MS = 200;


let log: Logger = null;
let context: ExtensionContext = null;
Expand Down Expand Up @@ -81,13 +84,23 @@ class ScrollMapWidget {
#log: Logger;
#terminal: Terminal = null;
#rootWidget: QWidget = null;
#repaintTimeout: DebouncedDoLater = null;
#permitMapCreation = true;

constructor(log: Logger, terminal: Terminal) {
this.#log = log;
this.#rootWidget = this.#createWidget();
this.#terminal = terminal;

this.#repaintTimeout = new DebouncedDoLater(() => {
// Quickly check if the widget has been closed or removed.
if (this.#rootWidget.window() != null) {
this.#permitMapCreation = true;
this.#rootWidget.repaint();
}
}, REPAINT_DELAY_MS);
const repaint = () => {
this.#repaintTimeout.trigger();
this.#rootWidget.repaint();
};
this.#terminal.onDidScreenChange(repaint);
Expand Down Expand Up @@ -212,25 +225,27 @@ class ScrollMapWidget {
paintRect.width() - SCREEN_BORDER_WIDTH, viewport.height * mapScale);

painter.end();
this.#permitMapCreation = false;
}

#drawPixelMap(painter: QPainter, pixelMap: PixelMap, y: number, rowHeight: number): void {
let blockRowY = 0;
const numberOfBlocks = pixelMap.getNumberOfBlocks();
for (let i=0; i<numberOfBlocks ; i++) {
const { qimage, rows } = pixelMap.getQImageAt(i);

painter.save();
const { qimage, rows } = pixelMap.getQImageAt(i, this.#permitMapCreation);

const matrix = mat2d.create();
mat2d.translate(matrix, matrix, [LEFT_PADDING + FRAME_WIDTH, y + blockRowY * rowHeight / ZOOM_FACTOR]);
mat2d.scale(matrix, matrix, [1, rowHeight / ZOOM_FACTOR]);
painter.setTransform(matrix);
if (qimage != null) {
painter.save();

painter.drawImage(0, 0, qimage, 0, 0, SCROLLMAP_WIDTH_CELLS, rows);
const matrix = mat2d.create();
mat2d.translate(matrix, matrix, [LEFT_PADDING + FRAME_WIDTH, y + blockRowY * rowHeight / ZOOM_FACTOR]);
mat2d.scale(matrix, matrix, [1, rowHeight / ZOOM_FACTOR]);
painter.setTransform(matrix);

painter.restore();
painter.drawImage(0, 0, qimage, 0, 0, SCROLLMAP_WIDTH_CELLS, rows);

painter.restore();
}
blockRowY += rows;
}
}
Expand Down Expand Up @@ -288,9 +303,9 @@ class PixelMap<S extends Screen = Screen> {
return this.#pixelBlocks.length;
}

getQImageAt(blockIndex: number): { qimage: QImage, rows: number} {
getQImageAt(blockIndex: number, generateImages: boolean): { qimage: QImage, rows: number} {
const pixelBlock = this.#pixelBlocks[blockIndex];
if (pixelBlock.qimage == null) {
if (generateImages && pixelBlock.qimage == null) {
const y = this.#blockIndexToY(blockIndex);
const image = this.#createQImage(this.#screen, y, pixelBlock.height);
pixelBlock.qimage = image;
Expand Down Expand Up @@ -341,6 +356,21 @@ class PixelMap<S extends Screen = Screen> {
this.#pixelBlocks.push({ qimage: null, height: rows });
existingRows += rows;
}

while (totalScreenRows < existingRows) {
const difference = existingRows - totalScreenRows;
const lastBlock = this.#pixelBlocks[this.#pixelBlocks.length-1];
const lastBlockHeight = lastBlock.height;

if (lastBlockHeight <= difference) {
this.#pixelBlocks.pop();
existingRows -= lastBlockHeight;
} else {
lastBlock.height -= difference;
lastBlock.qimage = null;
existingRows -= difference;
}
}
}

#createQImage(screen: Screen, y: number, rows: number): QImage {
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9212,6 +9212,7 @@ __metadata:
eslint: 8.53.0
eslint-config-extraterm: 1.0.0
eslint-plugin-unicorn: 42.0.0
extraterm-timeoutqt: 1.0.0
gl-matrix: ^3.3.0
qt-construct: 0.1.0
shx: ^0.3.2
Expand Down

0 comments on commit db170e8

Please sign in to comment.