Рисовать линию, ширина которой всегда равна ширине родительского элемента BoxElement? - PullRequest
7 голосов
/ 04 августа 2020

Я использую BoxElement из blessed для отображения истории чата.

Предложения добавляются с использованием pushLine. Для наглядности дни разделены линиями (другая строка добавлена ​​с использованием pushLine). Ширина каждой строки соответствует ширине родительской BoxElement.

Однако при изменении размера TUI строка больше не подходит.

У меня 2 вопроса:

  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();

При запуске кода ts-node ./Example.js он отображает следующее:

┌────────────────────────────────────────────────────────────────────────────────────────┐
│This is a line                                                                          │
│________________________________________________________________________________________│
│This is a second line                                                                   │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
│                                                                                        │
└────────────────────────────────────────────────────────────────────────────────────────┘

Изменение размера терминала дает следующий результат:

┌──────────────────────────────────────────────────────────┐
│This is a line                                            │
│__________________________________________________________│
│______________________________                            │
│This is a second line                                     │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
│                                                          │
└──────────────────────────────────────────────────────────┘

1 Ответ

5 голосов
/ 07 августа 2020

Кажется, что 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();

Насчет бонусного балла, теперь его должно быть довольно легко получить; трудная часть - центрировать линию, длина которой превышает ширину блока: если мы разделим ее на большее количество строк для центрирования, все индексы строк (рядом с разделенной центральной линией) изменятся, и их будет труднее отслеживать.

Возможный компромисс может заключаться в том, чтобы центрировать только строки короче ширины поля, заполняя их слева правильным количеством пробелов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...