绘制一条始终与其父 BoxElement 一样宽的线?

Mar*_*wie 7 javascript tui node.js blessed

我正在使用BoxElement来自祝福的显示聊天记录。

使用 来添加句子pushLine。为清楚起见,天数按行划分(使用 添加的另一个字符串pushLine)。每行与父行一样宽BoxElement

但是,如果调整 TUI 的大小,则该线不再适合。

我有两个问题:

  1. 那条线如何适应它的新宽度?
  2. (加分)如何将文本居中放置在该行的中间?

该问题的示例如下所示:

/**
 * Example.ts
 */
import * as blessed from 'blessed';

const screen = blessed.screen({
    smartCSR: true,
    title: 'Chatr',
    dockBorders: true
});

const chatBox = blessed.box({
    parent: screen,
    title: 'Chatbox',
    top: 'top',
    left: 'center',
    height: '100%',
    width: '100%',
    border: {
        type: 'line'
    },
});
screen.append(chatBox);
screen.render();

chatBox.pushLine("This is the first line");

 // This is the separator - and will not resize with the terminal 
chatBox.pushLine("_".repeat(chatBox.width as number - 2));

chatBox.pushLine("This is a second line");
screen.render();

Run Code Online (Sandbox Code Playgroud)

当代码运行时,ts-node ./Example.js它呈现:

??????????????????????????????????????????????????????????????????????????????????????????
?This is a line                                                                          ?
?________________________________________________________________________________________?
?This is a second line                                                                   ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
?                                                                                        ?
??????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

调整终端大小会得到以下结果:

????????????????????????????????????????????????????????????
?This is a line                                            ?
?__________________________________________________________?
?______________________________                            ?
?This is a second line                                     ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
?                                                          ?
????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

Dan*_*cci 5

它似乎blessed没有实现像分隔符这样的东西,但我们可以简单地用一个简单的类自己实现它们,该类存储每个分隔符的行索引并在resize事件发生时更改它们。就像是:

import * as blessed from "blessed";

// The required Separators class
class Separators {
  private box: any;
  private separators: number[] = [];

  public constructor(box: any) {
    this.box = box;

    box.on("resize", () => {
      const sep = this.sep();

      this.separators.forEach(line => {
        box.deleteLine(line);
        box.insertLine(line, sep);
      });
    });
  }

  public add(): void {
    const { box, separators } = this;

    separators.push(box.getLines().length);
    box.pushLine(this.sep());
  }

  private sep(): string {
    return "_".repeat((this.box.width as number) - 3);
  }
}

const screen = blessed.screen({
  smartCSR: true,
  title: "Chatr",
  dockBorders: true
});

const chatBox = blessed.box({
  parent: screen,
  title: "Chatbox",
  top: "top",
  left: "center",
  height: "100%",
  width: "100%",
  border: {
    type: "line"
  }
});
const sep = new Separators(chatBox); // <- the new Separator bound to the box
screen.append(chatBox);
screen.render();

chatBox.pushLine("This is the first line");

// This is the separator - and it resize with the terminal
sep.add();

chatBox.pushLine("This is a second line");
chatBox.pushLine("While this is the third line");

// This is another separator - it resize with the terminal as well
sep.add();

chatBox.pushLine("And last this is the last line");

screen.render();
Run Code Online (Sandbox Code Playgroud)

关于加分点,现在应该很容易实现了;困难的部分是将一条比框宽度长的线居中:如果我们将它分成更多的线到中心,所有的线索引(在分割的中心线旁边)都会改变并且可能变得更难跟踪它们。

一个可能的折衷方案是只接受比框宽度短的行居中,用适当的空格填充它们。