mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-03-09 13:00:53 +01:00
put static values for font size, re-render entire window when font size changes
This commit is contained in:
parent
5e68c6b2f7
commit
c66bee7657
@ -12,13 +12,15 @@ class ImageRendererModel {
|
||||
htmlImg : any;
|
||||
termOpts : TermOptsType;
|
||||
dataBuf : PtyDataBuffer;
|
||||
fontSize : number;
|
||||
|
||||
constructor(imgDivElem : any, context : RendererContext, termOpts : TermOptsType, isDone : boolean) {
|
||||
constructor(imgDivElem : any, context : RendererContext, termOpts : TermOptsType, isDone : boolean, fontSize : number) {
|
||||
this.dataBuf = new PtyDataBuffer();
|
||||
this.htmlImgDivElem = imgDivElem;
|
||||
this.termOpts = termOpts;
|
||||
this.context = context;
|
||||
this.isDone = mobx.observable.box(isDone, {name: "isDone"});
|
||||
this.fontSize = fontSize;
|
||||
this.reload(0);
|
||||
}
|
||||
|
||||
@ -39,8 +41,8 @@ class ImageRendererModel {
|
||||
let blob = new Blob([this.dataBuf.getData()], {type: "image/jpeg"});
|
||||
this.htmlImg = new Image();
|
||||
this.htmlImg.src = URL.createObjectURL(blob);
|
||||
this.htmlImg.style.maxHeight = termHeightFromRows(this.termOpts.rows) + "px";
|
||||
this.htmlImg.style.maxWidth = termWidthFromCols(this.termOpts.cols) + "px";
|
||||
this.htmlImg.style.maxHeight = termHeightFromRows(this.termOpts.rows, this.fontSize) + "px";
|
||||
this.htmlImg.style.maxWidth = termWidthFromCols(this.termOpts.cols, this.fontSize) + "px";
|
||||
this.htmlImgDivElem.replaceChildren(this.htmlImg);
|
||||
}
|
||||
|
||||
|
20
src/main.tsx
20
src/main.tsx
@ -483,7 +483,7 @@ class TerminalRenderer extends React.Component<{sw : ScreenWindow, line : LineTy
|
||||
}, {name: "computed-isFocused"}).get();
|
||||
let cmd = GlobalModel.getCmd(line); // will not be null
|
||||
let usedRows = sw.getUsedRows(line, cmd, width);
|
||||
let termHeight = termHeightFromRows(usedRows);
|
||||
let termHeight = termHeightFromRows(usedRows, GlobalModel.termFontSize.get());
|
||||
let termLoaded = this.termLoaded.get();
|
||||
return (
|
||||
<div ref={this.elemRef} key="term-wrap" className={cn("terminal-wrapper", {"focus": isFocused}, {"cmd-done": !cmd.isRunning()}, {"zero-height": (termHeight == 0)}, {"collapsed": collapsed})}>
|
||||
@ -707,12 +707,11 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width
|
||||
// header is 36px tall, padding+border = 6px
|
||||
// zero-terminal is 0px
|
||||
// terminal-wrapper overhead is 11px (margin/padding)
|
||||
// each terminal line 16px
|
||||
// inner-height, if zero-lines => 42
|
||||
// else: 53+(lines*16)
|
||||
// else: 53+(lines*lineheight)
|
||||
let height = 42; // height of zero height terminal
|
||||
if (usedRows > 0) {
|
||||
height = 53 + termHeightFromRows(usedRows);
|
||||
height = 53 + termHeightFromRows(usedRows, GlobalModel.termFontSize.get());
|
||||
}
|
||||
return (
|
||||
<div className={mainDivCn} id={this.getLineDomId()} ref={this.lineRef} data-lineid={line.lineid} data-linenum={line.linenum} data-windowid={line.windowid} style={{height: height}}>
|
||||
@ -1396,6 +1395,7 @@ class InfoRemoteShow extends React.Component<{}, {}> {
|
||||
</>
|
||||
);
|
||||
}
|
||||
let termFontSize = GlobalModel.termFontSize.get();
|
||||
return (
|
||||
<>
|
||||
<div key="info" className="info-remote">
|
||||
@ -1441,14 +1441,14 @@ class InfoRemoteShow extends React.Component<{}, {}> {
|
||||
</div>
|
||||
</If>
|
||||
</div>
|
||||
<div key="term" className={cn("terminal-wrapper", {"focus": isTermFocused}, (remote != null ? "status-" + remote.status : null))} style={{display: (ptyRemoteId == null ? "none" : "block"), width: termWidthFromCols(RemotePtyCols)}}>
|
||||
<div key="term" className={cn("terminal-wrapper", {"focus": isTermFocused}, (remote != null ? "status-" + remote.status : null))} style={{display: (ptyRemoteId == null ? "none" : "block"), width: termWidthFromCols(RemotePtyCols, termFontSize)}}>
|
||||
<If condition={!isTermFocused}>
|
||||
<div key="termblock" className="term-block" onClick={this.clickTermBlock}></div>
|
||||
</If>
|
||||
<If condition={inputModel.showNoInputMsg.get()}>
|
||||
<div key="termtag" className="term-tag">input is only allowed while status is 'connecting'</div>
|
||||
</If>
|
||||
<div key="terminal" className="terminal-connectelem" id="term-remote" data-remoteid={ptyRemoteId} style={{height: termHeightFromRows(RemotePtyRows)}}></div>
|
||||
<div key="terminal" className="terminal-connectelem" id="term-remote" data-remoteid={ptyRemoteId} style={{height: termHeightFromRows(RemotePtyRows, termFontSize)}}></div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -2604,8 +2604,8 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
|
||||
this.width.set(width);
|
||||
this.height.set(height);
|
||||
let {sw} = this.props;
|
||||
let cols = windowWidthToCols(width);
|
||||
let rows = windowHeightToRows(height);
|
||||
let cols = windowWidthToCols(width, GlobalModel.termFontSize.get());
|
||||
let rows = windowHeightToRows(height, GlobalModel.termFontSize.get());
|
||||
if (sw == null || cols == 0 || rows == 0) {
|
||||
return;
|
||||
}
|
||||
@ -2720,9 +2720,11 @@ class ScreenView extends React.Component<{screen : Screen}, {}> {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
let fontSize = GlobalModel.termFontSize.get();
|
||||
let swKey = sw.windowId + "-fs" + fontSize;
|
||||
return (
|
||||
<div className="screen-view" data-screenid={sw.screenId}>
|
||||
<ScreenWindowView key={sw.windowId} sw={sw}/>
|
||||
<ScreenWindowView key={swKey} sw={sw}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
51
src/model.ts
51
src/model.ts
@ -8,11 +8,9 @@ import {v4 as uuidv4} from "uuid";
|
||||
import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, RemotePtrType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType, ScreenDataType, ScreenWindowType, ScreenOptsType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, UIContextType, HistoryInfoType, HistoryQueryOpts, FeInputPacketType, TermWinSize, RemoteInputPacketType, FeStateType, ContextMenuOpts, RendererContext, RendererModel, PtyDataType, BookmarkType} from "./types";
|
||||
import {WSControl} from "./ws";
|
||||
import {ImageRendererModel} from "./imagerenderer";
|
||||
import {measureText} from "./textmeasure";
|
||||
import {measureText, getMonoFontSize} from "./textmeasure";
|
||||
|
||||
var GlobalUser = "sawka";
|
||||
const DefaultCellWidth = 7.203125;
|
||||
const DefaultCellHeight = 16;
|
||||
const RemotePtyRows = 8; // also in main.tsx
|
||||
const RemotePtyCols = 80;
|
||||
const MinTermCols = 10;
|
||||
@ -21,6 +19,9 @@ const ProdServerEndpoint = "http://localhost:1619";
|
||||
const ProdServerWsEndpoint = "ws://localhost:1623";
|
||||
const DevServerEndpoint = "http://localhost:8090";
|
||||
const DevServerWsEndpoint = "ws://localhost:8091";
|
||||
const DefaultTermFontSize = 12;
|
||||
const MinFontSize = 8;
|
||||
const MaxFontSize = 15;
|
||||
|
||||
// @ts-ignore
|
||||
const VERSION = __PROMPT_VERSION__;
|
||||
@ -34,26 +35,30 @@ type SWLinePtr = {
|
||||
sw : ScreenWindow,
|
||||
};
|
||||
|
||||
function windowWidthToCols(width : number) : number {
|
||||
let cols = Math.trunc((width - 50) / DefaultCellWidth) - 1;
|
||||
function windowWidthToCols(width : number, fontSize : number) : number {
|
||||
let dr = getMonoFontSize(fontSize);
|
||||
let cols = Math.trunc((width - 50) / dr.width) - 1;
|
||||
cols = boundInt(cols, MinTermCols, MaxTermCols);
|
||||
return cols;
|
||||
}
|
||||
|
||||
function windowHeightToRows(height : number) : number {
|
||||
let rows = Math.floor((height - 80)/DefaultCellHeight) - 1;
|
||||
function windowHeightToRows(height : number, fontSize : number) : number {
|
||||
let dr = getMonoFontSize(fontSize);
|
||||
let rows = Math.floor((height - 80) / dr.height) - 1;
|
||||
if (rows <= 0) {
|
||||
rows = 1;
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
function termWidthFromCols(cols : number) : number {
|
||||
return Math.ceil(DefaultCellWidth*cols) + 15;
|
||||
function termWidthFromCols(cols : number, fontSize : number) : number {
|
||||
let dr = getMonoFontSize(fontSize);
|
||||
return Math.ceil(dr.width*cols) + 15;
|
||||
}
|
||||
|
||||
function termHeightFromRows(rows : number) : number {
|
||||
return Math.ceil(DefaultCellHeight*rows);
|
||||
function termHeightFromRows(rows : number, fontSize : number) : number {
|
||||
let dr = getMonoFontSize(fontSize);
|
||||
return Math.ceil(dr.height*rows);
|
||||
}
|
||||
|
||||
function cmdStatusIsRunning(status : string) : boolean {
|
||||
@ -559,7 +564,7 @@ class ScreenWindow {
|
||||
loadImageRenderer(imageDivElem : any, line : LineType, cmd : Cmd) : ImageRendererModel {
|
||||
let cmdId = cmd.cmdId;
|
||||
let context = {sessionId: this.sessionId, screenId: this.screenId, windowId: this.windowId, cmdId: cmdId, lineId : line.lineid, lineNum: line.linenum};
|
||||
let imageModel = new ImageRendererModel(imageDivElem, context, cmd.getTermOpts(), !cmd.isRunning());
|
||||
let imageModel = new ImageRendererModel(imageDivElem, context, cmd.getTermOpts(), !cmd.isRunning(), GlobalModel.termFontSize.get());
|
||||
this.renderers[cmdId] = imageModel;
|
||||
return imageModel;
|
||||
}
|
||||
@ -571,7 +576,7 @@ class ScreenWindow {
|
||||
console.log("term-wrap already exists for", this.screenId, this.windowId, cmdId);
|
||||
return;
|
||||
}
|
||||
let cols = windowWidthToCols(width);
|
||||
let cols = windowWidthToCols(width, GlobalModel.termFontSize.get());
|
||||
let usedRows = GlobalModel.getTUR(this.sessionId, cmdId, cols);
|
||||
if (line.contentheight != null && line.contentheight != -1) {
|
||||
usedRows = line.contentheight;
|
||||
@ -586,6 +591,7 @@ class ScreenWindow {
|
||||
focusHandler: (focus : boolean) => this.setTermFocus(line.linenum, focus),
|
||||
isRunning: cmd.isRunning(),
|
||||
customKeyHandler: this.termCustomKeyHandler.bind(this),
|
||||
fontSize: GlobalModel.termFontSize.get(),
|
||||
});
|
||||
this.renderers[cmdId] = termWrap;
|
||||
if ((this.focusType.get() == "cmd" || this.focusType.get() == "cmd-fg") && this.selectedLine.get() == line.linenum) {
|
||||
@ -612,7 +618,7 @@ class ScreenWindow {
|
||||
}
|
||||
let termWrap = this.getRenderer(cmd.cmdId);
|
||||
if (termWrap == null) {
|
||||
let cols = windowWidthToCols(width);
|
||||
let cols = windowWidthToCols(width, GlobalModel.termFontSize.get());
|
||||
let usedRows = GlobalModel.getTUR(this.sessionId, cmd.cmdId, cols);
|
||||
if (usedRows != null) {
|
||||
return usedRows;
|
||||
@ -1535,6 +1541,7 @@ class InputModel {
|
||||
keyHandler: (e, termWrap) => { this.termKeyHandler(remoteId, e, termWrap)},
|
||||
focusHandler: this.setRemoteTermWrapFocus.bind(this),
|
||||
isRunning: true,
|
||||
fontSize: GlobalModel.termFontSize.get(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1827,6 +1834,7 @@ class Model {
|
||||
authKey : string;
|
||||
isDev : boolean;
|
||||
activeMainView : OV<"session" | "history" | "bookmarks"> = mobx.observable.box("session", {name: "activeMainView"});
|
||||
termFontSize : OV<number> = mobx.observable.box(DefaultTermFontSize, {name: "termFontSize"});
|
||||
|
||||
inputModel : InputModel;
|
||||
bookmarksModel : BookmarksModel;
|
||||
@ -1863,6 +1871,18 @@ class Model {
|
||||
return ProdServerEndpoint;
|
||||
}
|
||||
|
||||
setTermFontSize(fontSize : number) {
|
||||
if (fontSize < MinFontSize) {
|
||||
fontSize = MinFontSize;
|
||||
}
|
||||
if (fontSize > MaxFontSize) {
|
||||
fontSize = MaxFontSize;
|
||||
}
|
||||
mobx.action(() => {
|
||||
this.termFontSize.set(fontSize);
|
||||
})();
|
||||
}
|
||||
|
||||
getBaseWsHostPort() : string {
|
||||
if (this.isDev) {
|
||||
return DevServerWsEndpoint;
|
||||
@ -2749,12 +2769,11 @@ let GlobalCommandRunner : CommandRunner = null;
|
||||
if ((window as any).GlobalModel == null) {
|
||||
(window as any).GlobalModel = new Model();
|
||||
(window as any).GlobalCommandRunner = new CommandRunner();
|
||||
(window as any).getMonoFontSize = getMonoFontSize;
|
||||
}
|
||||
GlobalModel = (window as any).GlobalModel;
|
||||
GlobalCommandRunner = (window as any).GlobalCommandRunner;
|
||||
|
||||
window.measureText = measureText;
|
||||
|
||||
export {Model, Session, Window, GlobalModel, GlobalCommandRunner, Cmd, Screen, ScreenWindow, riToRPtr, windowWidthToCols, windowHeightToRows, termWidthFromCols, termHeightFromRows, getPtyData, getRemotePtyData};
|
||||
|
||||
|
||||
|
11
src/term.ts
11
src/term.ts
@ -29,6 +29,7 @@ type TermWrapOpts = {
|
||||
dataHandler? : (data : string, termWrap : TermWrap) => void,
|
||||
isRunning : boolean,
|
||||
customKeyHandler? : (event : any, termWrap : TermWrap) => boolean,
|
||||
fontSize: number,
|
||||
};
|
||||
|
||||
// cmd-instance
|
||||
@ -48,6 +49,7 @@ class TermWrap {
|
||||
termSize : TermWinSize;
|
||||
focusHandler : (focus : boolean) => void;
|
||||
isRunning : boolean;
|
||||
fontSize : number;
|
||||
|
||||
constructor(elem : Element, opts : TermWrapOpts) {
|
||||
opts = opts ?? ({} as any);
|
||||
@ -57,6 +59,7 @@ class TermWrap {
|
||||
this.winSize = opts.winSize;
|
||||
this.focusHandler = opts.focusHandler;
|
||||
this.isRunning = opts.isRunning;
|
||||
this.fontSize = opts.fontSize;
|
||||
if (this.flexRows) {
|
||||
this.atRowMax = false;
|
||||
this.usedRows = mobx.observable.box(opts.usedRows ?? (opts.isRunning ? 1 : 0), {name: "term-usedrows"});
|
||||
@ -69,13 +72,13 @@ class TermWrap {
|
||||
this.termSize = {rows: opts.termOpts.rows, cols: opts.termOpts.cols};
|
||||
}
|
||||
else {
|
||||
let cols = windowWidthToCols(opts.winSize.width);
|
||||
let cols = windowWidthToCols(opts.winSize.width, opts.fontSize);
|
||||
this.termSize = {rows: opts.termOpts.rows, cols: cols};
|
||||
}
|
||||
let theme = {
|
||||
foreground: "#d3d7cf",
|
||||
};
|
||||
this.terminal = new Terminal({rows: this.termSize.rows, cols: this.termSize.cols, fontSize: 12, fontFamily: "JetBrains Mono", theme: theme});
|
||||
this.terminal = new Terminal({rows: this.termSize.rows, cols: this.termSize.cols, fontSize: opts.fontSize, fontFamily: "JetBrains Mono", theme: theme});
|
||||
this.terminal._core._inputHandler._parser.setErrorHandler((state) => {
|
||||
this.numParseErrors++;
|
||||
return state;
|
||||
@ -238,8 +241,8 @@ class TermWrap {
|
||||
}
|
||||
|
||||
resizeWindow(size : WindowSize) : void {
|
||||
let cols = windowWidthToCols(size.width);
|
||||
let rows = windowHeightToRows(size.height);
|
||||
let cols = windowWidthToCols(size.width, this.fontSize);
|
||||
let rows = windowHeightToRows(size.height, this.fontSize);
|
||||
this.resize({rows, cols});
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,17 @@
|
||||
let canvasElem = document.createElement("canvas");
|
||||
let MonoFontSizes : {height : number, width : number}[] = [];
|
||||
|
||||
MonoFontSizes[8] = {height: 11, width: 4.797};
|
||||
MonoFontSizes[9] = {height: 12, width: 5.398};
|
||||
MonoFontSizes[10] = {height: 13, width: 6};
|
||||
MonoFontSizes[11] = {height: 15, width: 6.602};
|
||||
MonoFontSizes[12] = {height: 16, width: 7.203};
|
||||
MonoFontSizes[13] = {height: 18, width: 7.797};
|
||||
MonoFontSizes[14] = {height: 19, width: 8.398};
|
||||
MonoFontSizes[15] = {height: 20, width: 9};
|
||||
|
||||
function getMonoFontSize(fontSize : number) : {height : number, width : number} {
|
||||
return MonoFontSizes[fontSize];
|
||||
}
|
||||
|
||||
function measureText(text : string, textOpts? : {pre? : boolean, mono? : boolean, fontSize? : number|string}) : DOMRect {
|
||||
if (textOpts == null) {
|
||||
@ -28,4 +41,4 @@ function measureText(text : string, textOpts? : {pre? : boolean, mono? : boolean
|
||||
return measureDiv.getBoundingClientRect()
|
||||
}
|
||||
|
||||
export {measureText};
|
||||
export {measureText, getMonoFontSize};
|
||||
|
Loading…
Reference in New Issue
Block a user