[RFC] ColorD

Adam D. Ruppe destructionator at gmail.com
Fri Oct 26 10:35:05 PDT 2012


Here we go, some more basic functions:

http://arsdnet.net/dcode/terminal.d

The unix stuff is more implemented than the windows.


Let's walk through main and I'll discuss why I'm doing things the 
way I am. I'm throwing this out just to show one possible way 
this can be done and to explain why I like this way. Feel free to 
take some or all of my code if you want.


	auto terminal = Terminal(ConsoleOutputType.cellular);

First, the terminal is a separate type, a struct, rather than 
just magic functions. This way it can use the struct destructor 
to reset things to normal.

The argument here is either linear or cellular - do you want line 
based output or do you want to control the whole screen as a grid 
of cells?

If you use cellular, it will use the alternative screen buffer on 
unix terminals. IIRC Windows works basically the same way. This 
is what we want for a TUI app.

The escape sequences to make this happen is based on the 
envrionment variable TERMCAP, which is set by gnu screen, xterm, 
and most other emulators.

It is *not* set by the linux console or rxvt on my box, so this 
isn't perfect yet, but it is a start. If it can't find a 
capability in there, it simply ignores those method calls, 
meaning it should be backward compatible (once fully implemented 
- I haven't done this on title yet.)

	terminal.setTitle("Basic I/O");

All changes are done with methods. This is how Windows does it 
and is cleaner anyway.

	auto input = terminal.captureInput(ConsoleInputFlags.raw);

To get real time input, you use a special method which returns an 
input struct. Which could probably be an input range actually but 
isn't now.

Anyway the reason is you have to change the terminal mode in 
linux to get real time input. Otherwise it will be line buffered. 
Again, a struct lets us reset the mode automatically in the 
destructor. The flags let you control automatic echo.

	terminal.color(Color.green | Bright, Color.black);

I insist that you set foreground and background colors together. 
This ensure you get readable text.

The colors are defined with a platform independent color enum and 
you can flag in bright to get brighter colors.


BTW I'm thinking about calling it LowContrast instead of 
bright... then your color definitions can always be the same 
regardless of bg, and it automatically flips the bright bit if 
needed. But since I'm forcing you to specify background here too 
it isn't a big deal with now.


	int centerX = terminal.width / 2;
	int centerY = terminal.height / 2;

I prefer width and height to rows and columns. I think more in 
terms of gui here.

	while(true) {
		if(input.kbhit()) {

Since we have real time capture, can poll for new input instead 
of blocking.

			auto c = input.getch();

Get our character... (BTW this function still needs a lot of work)

			if(c == 'q' || c == 'Q')
				break;
			terminal.moveTo(centerX, centerY);
			terminal.writef("%c", c);
			terminal.flush();

And output the stuff, centering the text. All output methods are 
attached to the terminal to ensure the proper api stuff is 
handled.

		usleep(10000);

This is just there so we don't eat too much cpu waiting on input.


More information about the Digitalmars-d mailing list