Turbo Vision 2.0 - a recriação da UI de texto dos anos 90
(github.com/magiblot)- Porta open source que moderniza, com suporte multiplataforma + Unicode, o framework de UI de texto da Borland dos anos 90
- Ao criar apps de terminal, não é preciso lidar com compatibilidade de terminal — funciona com o mesmo código em Linux, Windows e DOS
- Janelas sobrepostas redimensionáveis, menus suspensos, diálogos, botões, barras de rolagem, campos de entrada, caixas de seleção, botões de opção e outros widgets de TUI já vêm embutidos, então é só usar sem precisar implementar tudo do zero
- Suporte completo a Unicode UTF-8 — mantém a API existente baseada em
char, mas consegue lidar com caracteres CJK de largura total, caracteres combinantes e até emoji; com uma única chamada amoveStr(), rolagem e truncamento de multibyte são tratados automaticamente - Aproveita o suporte a
setlocaleem UTF-8 da Microsoft RTL, então código comostd::ifstream f("コンピュータ.txt")funciona no Windows sem alterações - Suporte a true color de 24 bits — expandido das 16 cores originais para RGB, xterm-256 e cores padrão do terminal; se o terminal não oferecer suporte, faz quantização automática para a cor mais próxima
- Suporta toda a entrada/saída moderna, como roda do mouse, botão do meio, clique triplo, tamanho de tela de até 32767 linhas/colunas e eventos de redimensionamento de janela
- Integração nativa com a área de transferência do sistema: no Windows/macOS funciona imediatamente, e até em ambientes remotos via SSH é possível copiar/colar com X11 forwarding ou códigos de escape OSC 52
- É possível compilar o código-fonte original do Turbo Vision da era Borland C++ quase sem modificações
- Suporte ao sistema de build CMake; com
./vcpkg install tvisionem uma única linha a instalação está pronta, e ao adicionaradd_subdirectorycomo submódulo do CMake as dependências são vinculadas automaticamente - Requer C++14 ou superior e libncursesw / licença MIT
1 comentários
Comentários do Hacker News
Fiquei muito feliz de ver este repositório chegar à front page e, neste momento, estou fazendo eu mesmo um wrapper para ele
Estou rodando o Turbo Vision no macOS sobre .NET, e a sensação é quase mágica
Estou fornecendo uma API de nível mais alto, além de encapsular ou melhorar a API de palette, que já está bem antiquada, e também adicionando layout
Ainda está tudo em um repositório privado em pleno desenvolvimento; hoje estou ajustando a palette com base na surface onde os controles foram colocados, amanhã lapido outra parte, e assim vou refinando continuamente
Ainda faltam coisas como organizar o layout e adicionar controles básicos que fazem falta para os padrões de hoje
Já usei Terminal.Gui antes, mas talvez por estar em transição para a v2, foi bem difícil lidar com ele sem bugs, e o Claude também mostrou muito bem o que não se deve fazer ao criar uma biblioteca TUI sem considerar um terminal real
Então eu já vinha pensando que seria ótimo ter uma versão moderna do Turbo Vision, e aí encontrei este repositório; quando vi que ele ainda tinha suporte a Unicode, fiquei realmente grato
https://www.remobjects.com/elements/oxygene/
https://www.remobjects.com/elements/
Eu também estou fazendo um wrapper em .NET e, embora provavelmente esteja menos avançado, quero imitar o máximo possível a API do Windows Forms e até incluir um designer TUI com drag-and-drop
O exemplo está aqui: https://github.com/brianluft/terminalforms/tree/main/src/TerminalFormsDemo
A maior parte da integração complicada do lado de C++ foi resolvida aqui: https://github.com/brianluft/terminalforms/tree/main/src/tfcore
Exportei funções C simples para que pudessem ser chamadas via P/Invoke, e deixei o lado em C# focado principalmente em organizar a estrutura de classes
No começo, insisti na ideia de que tudo que fosse possível em C++ também deveria ser possível em C#, mas isso ficou complexo demais; cheguei ao ponto de colocar objetos C++ dentro de buffers de C# com placement new, praticamente como se estivesse herdando classes C++ do lado de C#, e o design desmoronou
No fim, mudei para uma abordagem mais direta, menos flexível, mas muito mais simples, e decidi deixar a flexibilidade no lado do C#
Fiquei curioso para saber como você estruturou o seu sistema de P/Invoke
Acho que isso me impediu de fazer tentativas inúteis, como criar aplicativos para GEOS ou entrar para a equipe de uma pessoa só do Hurd
Cheguei a experimentar Terminal.Gui, mas o lado do TV me atrai mais, então já pensei em fazer um wrapper; adoraria ver isso quando for público
Minha carreira de programação literalmente começou numa caçamba de lixo nos anos 90
Peguei um livro de Turbo Vision que alguém tinha jogado fora e me apaixonei imediatamente por aquela TUI azulada que qualquer um podia criar
A versão original vinha no Turbo Pascal 6, e o port para C++ apareceu depois
Então isto pode ser visto como um port moderno de um port
A Borland tinha outros frameworks parecidos nesse sentido: o OWL também começou primeiro no Turbo Pascal for Windows 1.5, e boa parte das ferramentas do C++ Builder na verdade foi escrita em Delphi
O Object Pascal do Turbo Pascal 5.5, e depois o Turbo Vision do 6, foram minha porta de entrada para OOP, e sinto que tive sorte por ter começado por esse caminho
Mesmo em um ambiente como o MS-DOS, dava para aprender muito bem as vantagens de frameworks trazidas por OOP e pelo Turbo Vision
Quando a Borland lançou Turbo Pascal, Turbo C++, TurboVision, parecia que um universo de possibilidades se abria
O desempenho dos compiladores era excelente e os manuais pareciam obras de arte; queria ainda ter aqueles livros
Isso é simplesmente um tesouro cultural
No começo dos anos 90, aprendi C/C++ praticamente sozinho lendo só a pilha de livros da Borland que vinha com o Turbo C++; hoje em dia é difícil até imaginar uma cena dessas, de alguém aprendendo assim apenas com livros de referência
Os frameworks TUI mais novos sempre pareciam ter alguma coisa faltando, e agora vou usá-lo de novo para verificar se isso era só nostalgia
Pretendo colocá-lo na minha próxima ferramenta, e queria aplaudir muito quem fez isso
Tirando GW-BASIC e MS-DOS, era tudo Borland: Turbo BASIC, Turbo Pascal, Turbo C++ para MS-DOS e Windows 3.x, Turbo Vision, OWL
Só fui usar VC++ lá pela versão 5, e o MFC sempre pareceu sem graça demais perto dos produtos da Borland
Até hoje é raro ver algo que realmente acompanhe a capacidade RAD do C++ Builder, e mesmo o .NET levou bastante tempo para acertar a história de programação de baixo nível e AOT no estilo do Delphi
Acho que desenvolvedores de Go, C++ e Rust deveriam receber algumas cópias do Turbo Pascal 7 para MS-DOS e do Delphi moderno
O Turbo Vision 2.0 ainda é bastante prático hoje; cheguei a usá-lo diretamente em um trabalho de prototipagem há cerca de um ano
Tentei criar um frontend Turbo Vision para o depurador LLDB, para que funcionasse como o Turbo Debugger da Borland, e na maior parte deu certo
Foi surpreendente sentir que ele continuava exatamente de onde parou em 199x, e também consegui compilar e executar código de 1993 sem grandes problemas
Também existe uma versão melhor do editor interno, baseada em Scintilla, com recursos como syntax highlighting, mas as modificações que eu queria fazer não deram muito certo, então talvez eu precise pedir ajuda ao autor
Porém, no sentido moderno de conhecimento compartilhado, falta documentação, então é difícil perguntar no Stack Overflow ou para uma IA; tive que aprender olhando o código de exemplo e relendo algumas vezes livros sobre Turbo Vision, do jeito antigo
O layout manual é bem trabalhoso, então seria ótimo ter algo como o layout automático do Qt, e também sinto falta de splitter, embora não pareça difícil de implementar
Outra coisa que me surpreendeu foi como o TV é, na prática, pequeno e compacto. Nos anos 90 ele parecia enorme
No geral, o trabalho de modernização ficou realmente muito bom, e eu gosto muito disso
O Turbo Vision originalmente tinha uma grande quantidade de documentação de alta qualidade
Na verdade, acho que quem sofre mais com falta de documentação é o lado moderno
https://archive.org/details/bitsavers_borlandTurrogrammingGuide1992_25707423
Ver um monte de diretivas do cmake me dá uma vontade estranha de voltar ao passado
No Turbo C ou no Pascal, bastava apertar F9 e tudo rodava
Por outro lado, sinto que isso também mostra a incompetência das nossas toolchains
Hoje em dia, o ideal seria apontar para um compilador online e executar na hora, ou baixar, abrir uma pasta e rodar; em vez de ferramenta, isso virou quase um ritual
./configure && make && make install ainda deveria ser o gold standard
Este é só um dos ports/clones do Turbo Vision
No lado de C++, também existe este aqui: https://github.com/kloczek/tvision
A versão que entra no FreePascal/Lazarus foi escrita em Pascal, e também há uma em Rust que parece meio vibe-coded: https://github.com/aovestdipaperino/turbo-vision-4-rust
Rodando isso no terminal, perde-se um pouco da sensação essencial que o mouse na tela em modo texto costumava dar
Numa tela real em modo texto, ele não parecia um ponteiro de mouse, mas sim um bloco amarelo movido pelo mouse
Fico curioso se alguém já testou isso em modo texto Linux de alta resolução com GPM
Era mostrado invertendo as cores da célula sobre a qual estava, e como a janela principal que preenchia a maior parte da tela geralmente era azul-escura, muitas vezes o resultado parecia um bloco amarelo-claro
Recomendo um episódio recente do Wookash podcast sobre Chuck Jazdzewski
Ele fez parte da equipe original que criou o Turbo Vision, e o episódio fala bastante sobre esse ecossistema como um todo
Eu ainda prefiro o Turbo Vision de verdade, ou seja, a versão em Pascal, em vez da versão em C++
A de C++ sempre pareceu mais uma adaptação da de Pascal
Por exemplo, em Pascal
usesé uma palavra-chave, enquanto incluir módulos com#definesempre pareceu meio gambiarraBem, talvez hoje isso já não faça tanta diferença
A IDE em modo texto também usa o Free Vision
https://wiki.lazarus.freepascal.org/images/1/19/Userscreen.png
Mas a principal diferença é que o Free Vision e o Turbo Vision usam o tipo
objectda época do Turbo Pascal 5.5, e nãoclassdo DelphiCom
class, graças ao RTTI, fica fácil implementar coisas como serialização automática; já comobject, isso não existe, então, para distinguir tipos diferentes em tempo de execução, é preciso fazer serialização manual, registrando o ponteiro VMT que fica em um offset fixo do ponteiro do objetoO Free Pascal até acrescentou algumas conveniências ao
object, como private/protected/public e property, mas o Free Vision não usa essas extensões, porque ele implementa a API original do Turbo Vision