magiblot / tvision

A modern port of Turbo Vision 2.0, the classical framework for text-based user interfaces. Now cross-platform and with Unicode support.
Other
2k stars 151 forks source link

256 color terminal support #19

Open mooskagh opened 3 years ago

mooskagh commented 3 years ago

I suspect the answer is "no", but is there any chance to have 256 color support in the future?

Thanks!

magiblot commented 3 years ago

Yes! But not yet. I first need more free time, and then I'll have to address the following issues:

Cheers.

pkral78 commented 3 years ago

I would like to point out these articles: https://jexer.sourceforge.io/ and especially https://jexer.sourceforge.io/evolution.html

magiblot commented 3 years ago

What do you expect to be able to do with 256/true color support?

pkral78 commented 3 years ago

What do you expect to be able to do with 256/true color support?

Is this question about wider color support or moreabout general Sixel graphics?

magiblot commented 3 years ago

As I understand it, the OP's question is about text-mode color (https://gist.github.com/XVilka/8346728). I do not intend to support Sixel graphics.

mooskagh commented 3 years ago

Yeah I only meant text mode colors, and 256 colors would be more than enough for my case.

I was considering using tvision to implement a tool which would have a window with a very rich syntax highlighting, and it felt that 16 colors would not be enough (there were ~30 different categories and total, and also it would be nice to highlight similar categories by similar [but not completely the same] colors). (in the end I decided to do graphical way and started to do that in GTK+)

Plus, 256 color text interfaces look much more beautiful, see for example this tool that is called GoAccess: image

electroly commented 3 years ago

I had given some thought to how tvision on modern platforms might support extended colors in palettes, as I'm interested in that too. I'm willing to subclass all the controls and copy-paste their draw implementation from tvision so I can replace the color handling with some kind of custom mechanism, but if it could be weaseled into the existing palette support, so much the better. I'm specifically interested in allowing the user to pick custom dialog backgrounds, custom button colors, etc. Visual Basic for DOS allows this with a simple color picker and I thought it would be nice to have this in TMBASIC.

I noticed that blink doesn't work in a lot of modern terminals, and there's a bit dedicated to blink in palette color definitions. I don't think any of the built-in controls use blinking text (correct me if I'm wrong). Could a compile-time define allow that blink bit to be repurposed to mean "take the rest of the bits and use it as an index into an extended palette" where the extended palette has a similar structure, but with either 2-byte (256 color fg/bg) or 6-byte (24-bit) entries? With the compile-time symbol not defined, it would exclude that logic and the extended palette array and continue to do what tvision does now. Just a thought; I haven't looked into it very deeply, but I'm interested.

electroly commented 3 years ago

Oh, I have a second unrelated use case in TMBASIC. I want the user to be able to write TUI apps or full-screen console apps (e.g. colorful text-based games like ZZT), but critically I'd also like the ability to combine the two and have tvision dialogs floating above full-screen console games. Imagine like a betting window for a blackjack game that floats above a custom-drawn blackjack table. If tvision supports extended colors, I think I could run everything under tvision and simply draw onto the desktop for custom-drawn stuff, and then it's no big deal to occasionally pop dialogs up on top of it. In the absence of this support, I don't know how I'd pull it off if I wanted more than tvision's 8 bg and 16 fg colors; I think I'd have to make TUI and full-screen drawing mutually exclusive, using tvision for the former and using ncurses directly for the latter.

magiblot commented 3 years ago

Thank you everyone for the comments.

Integrating extended color support into the Turbo Vision API affects two different parts of the original API:

I want the user to be able to write TUI apps or full-screen console apps (e.g. colorful text-based games like ZZT), but critically I'd also like the ability to combine the two and have tvision dialogs floating above full-screen console games.

I can confirm this will be possible at least by manipulating TScreenCell manually. This is notcurses-demo running inside a Turbo Vision application:

Screenshot_20210224_020931

Cheers.

electroly commented 3 years ago

But not all hope is lost. The Palette API is not only about the TPalette type, but also the uchar TView::mapColor(uchar color) method ... bypassing the Palette API implies that any palette-switching functionality will have to be implemented manually by the application.

This sounds like a great approach; I like this. It's probably cleaner than hijacking the blink bit. Implementing my own mapColor for each control would be easy enough, and I could offer per-view palette customizations without having to override draw.

Would my mapColor implementations need to know whether the terminal supports extended colors? Seems like they would have to know and provide appropriate color mappings for the terminal's capabilities.

Very nice demo image. I'm excited about the possibilities!

magiblot commented 3 years ago

Would my mapColor implementations need to know whether the terminal supports extended colors? Seems like they would have to know and provide appropriate color mappings for the terminal's capabilities.

No. Turbo Vision will take care of converting the color you want to display to what the terminal can display. In other words: you should be able to use extended colors without knowing your terminal's capabilities or even knowing what a terminal is.

For example:

COLORTERM=truecolor (original) TERM=xterm-256color
Screenshot_20210224_025038 2 Screenshot_20210224_025059 2
TERM=xterm-16color TERM=xterm (bold as bright)
Screenshot_20210224_025138 2 Screenshot_20210224_025422 2
magiblot commented 3 years ago

But bypassing the Palette API implies that any palette-switching functionality will have to be implemented manually by the application.

This turns out to be too much of a disadvantage. Just think in how many classes we'd have to override the mapColor method to get the bottom panel right in this dialog:

Screenshot_20210224_175029

It's not worth the effort. So I think it's a good idea to keep on using palettes instead of overriding mapColor. I found a way to accomplish this without increasing complexity:

Screenshot_20210224_174047

okbob commented 3 years ago

st 24. 2. 2021 v 18:09 odesílatel magiblot notifications@github.com napsal:

But bypassing the Palette API implies that any palette-switching functionality will have to be implemented manually by the application.

This turns out to be too much of a disadvantage. Just think in how many classes we'd have to override the mapColor method to get the bottom panel right in this dialog:

[image: Screenshot_20210224_175029] https://user-images.githubusercontent.com/20713561/109035732-397e1380-76c9-11eb-804c-18ba23c3ebcc.png

It's not worth the effort. So I think it's a good idea to keep on using palettes instead of overriding mapColor. I found a way to accomplish this without increasing complexity:

[image: Screenshot_20210224_174047] https://user-images.githubusercontent.com/20713561/109036204-a72a3f80-76c9-11eb-8906-55a27d246280.png

This looks pretty well

You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub https://github.com/magiblot/tvision/issues/19#issuecomment-785229621, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEFO42Y526BGBFNFERMHK3TAUXFZANCNFSM4SU63LNA .

electroly commented 3 years ago

FWIW, I'm probably already going to subclass all of the views that ship with tvision to add hooks for the BASIC bindings. It may be too much hassle for apps that just want to cook up a tvision GUI with fancy colors, but at least for TMBASIC's purposes I'm willing to do it since I'll do it once and they will serve all the BASIC programs the same way.

I didn't mention it above but the limit of 256 palette entries is kind of an issue on its own; unless I subclass and override draw or mapColor across the board, I won't be able to offer unlimited per-window palette customization for more than a couple windows because there aren't enough palette entries to go around:

// 0x08 - 0x0F: cpBlueWindow
// 0x10 - 0x17: cpCyanWindow
// 0x18 - 0x1F: cpGrayWindow
// 0x20 - 0x3F: cpGrayDialog
// 0x40 - 0x5F: cpBlueDialog
// 0x60 - 0x7F: cpCyanDialog

These six window styles already consume half of the available palette entries. I had to evict THelpWindow's palette (0x80 - 0x87) from my app palette because I needed to free up some palette entries.

In Visual Basic for DOS (and in modern Windows Forms) there is no concept of a palette, they just have a foreground and background color for each view that you can change individually. I wonder if an alternative solution here is to do something like that. What I really want is just the ability to set fields in, e.g., TButton that specify the button color, shadow color, unselected text color, and selected text color, with a default value (-1?) meaning "use the palette". If tvision offered these, there would be no need to subclass in order to set the colors. If I subclass the views and override either mapColor or draw to implement custom color handling, this is exactly how I'll present it to the callers.

pkral78 commented 3 years ago
  • So TPalette has the issue that it uses a single data type to represent two different things: indices and color attributes. The result is that when you define the palette of a class you cannot use the type system to express whether you are defining colors or indices.

So what about split this type into two? Is it feasible ?

magiblot commented 3 years ago

I've pushed extended color support into the colors branch. I'd like to make sure it doesn't break anything in @electroly's project (the only active one I know of) before merging it into master.

There's a new section at the end of the README that explains briefly how it works.

Basically, it comes down to the following:

Turbo Vision takes care of mapping the provided colors to the current terminal capabilities. Client applications need not worry about this.

Speaking of terminal capabilities: for the moment, these are only detected properly on Unix systems (where Ncurses/Termcap/Terminfo are widely used). Windows applications are capped to 16 colors because I have yet to investigate what can be done there (although setting the COLORTERM environment variable to truecolor or 24bit will unlock true color support in either case).

Unfortunately, I haven't yet published any application that allows you to play with these features, so you'll either have to wait or attempt to write one yourselves.

Cheers.

electroly commented 3 years ago

I updated to tvision commit 79182b1a742a9944f89e632cf524b26d940e805f and ran a build and test on all platforms, no problems at all. Looks good! I'll give the new capabilities a try.

electroly commented 3 years ago

I whipped up a quick 256-color test. Looks good! I tested both overriding mapColor and passing TColorAttr to TDrawBuffer. Nice work!

image

magiblot commented 3 years ago

Great!