By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,660 Members | 1,218 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,660 IT Pros & Developers. It's quick & easy.

Design question: A little C++ header for colorizing text in Linux -- Comments/Ideas

P: n/a
I often do a lot of text-mode programming in Linux and wanted to use
colors in text mode, and found the ncurses library needlessly complex
for small applications. So I wrote my own little header to handle
colors in C++. (The code follows.)

This allows me to write code like

cout << gotoxy(10, 11)
<< color(lightcyan, blue)
<< "some text whatever";

I'd like to know how I could implement this more efficiently or in a
better way. Here are some questions I have:

(1) What exactly is a manipulator and how do I write one? How could a
manipulator help here?

(2) All that color and gotoxy do is simply output the corresponding
ANSI escape sequence string. How could I best make a color pair map
into its corresponding ANSI escape string?

(3) Could I selectively output the characters for gotoxy and color
(they simply output the corresponding ANSI escape sequences) only when
it is used with cout and not an ofstream object?

(4) How could I make this more easy to use?

Thanks in advance :)

-----------------------------------------------------

Here's the code:

//---------------------------------------------
// color.h
//---------------------------------------------

#ifndef COLOR_H
#define COLOR_H

#include <iostream>
using namespace std;

enum ColorName
{
black,
red,
green,
brown,
blue,
magenta,
cyan,
lightgray,

darkgray,
lightred,
lightgreen,
yellow,
lightblue,
lightmagenta,
lightcyan,
white
};
struct color
{
color(ColorName f = white, ColorName b = black)
:
fore(f),
back(b)
{}
ColorName fore;
ColorName back;
};
inline ostream& operator<<(ostream& o, const color& c)
{
if(c.fore > lightgray) // bold color
o << "\033[1;3" << c.fore - lightgray - 1 << "m";
else
o << "\033[0;3" << c.fore << "m";

return o << "\033[4" << c.back << "m";
}
struct gotoxy
{
gotoxy(int x_, int y_)
:
x(x_),
y(y_)
{}

int x;
int y;

};
inline ostream& operator<<(ostream& o, const gotoxy& g)
{
return o << "\033[" << g.y << ";" << g.x << "f";
}

#endif
Jul 19 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
"Slash" <de******@hotmail.com> wrote...
I often do a lot of text-mode programming in Linux and wanted to use
colors in text mode, and found the ncurses library needlessly complex
for small applications. So I wrote my own little header to handle
colors in C++. (The code follows.)

This allows me to write code like

cout << gotoxy(10, 11)
<< color(lightcyan, blue)
<< "some text whatever";

I'd like to know how I could implement this more efficiently or in a
better way.
I think your implementation is good enough. What inefficiencies do
you see in it? What is not good about it, in your opinion?
Here are some questions I have:

(1) What exactly is a manipulator and how do I write one? How could a
manipulator help here?
You have successfully written two manipulators. Why are you asking
about how to write them?
(2) All that color and gotoxy do is simply output the corresponding
ANSI escape sequence string. How could I best make a color pair map
into its corresponding ANSI escape string?
What don't you like about the way you do it now? I can see only one
marginally acceptable improvement: a table of ANSI strings instead
of the calculation. Still, to prove that it's an improvement, one
would need to profile both versions.
(3) Could I selectively output the characters for gotoxy and color
(they simply output the corresponding ANSI escape sequences) only when
it is used with cout and not an ofstream object?
No, for all intents and purposes 'std::cout' _could_ be a file. It
is impossible to tell without being platform-specific, AFAIK.

(4) How could I make this more easy to use?


It's easy as it is. How much easier do you expect it to get?

Keep in mind, though, that your code is NOT going to work on systems
that do not have ANSI terminals (and those are quite a few).

Victor
Jul 19 '05 #2

P: n/a
de******@hotmail.com (Slash) writes:
I often do a lot of text-mode programming in Linux and wanted to use
colors in text mode, and found the ncurses library needlessly complex
for small applications. So I wrote my own little header to handle
colors in C++. (The code follows.)

This allows me to write code like

cout << gotoxy(10, 11)
<< color(lightcyan, blue)
<< "some text whatever";

I'd like to know how I could implement this more efficiently or in a
better way. Here are some questions I have:
You still need libncurses, or libslang, or terminfo. If you don't,
you can't cope with non-ANSI terminals or output redirection to
non-terminal destinations.

ncurses isn't /that/ difficult. Your existing API is quite good, and
should wrap ncurses with little difficulty. You could have a base
object representing a window, and do

window << color(blue, yellow) << message;

and have this wrap printw() et. al..
(1) What exactly is a manipulator and how do I write one? How could a
manipulator help here?
Do you mean in the sense of <iomanip>? These are used to control
formatting of numbers, field widths, alignment etc. I don't think you
need to use them in your header, but users of the header would use
them to format their output appropriately.

If you output to your own class (rather than a std::ostream) you could
use your own custom manipulators to set the colours, coordinates,
etc..
(2) All that color and gotoxy do is simply output the corresponding
ANSI escape sequence string. How could I best make a color pair map
into its corresponding ANSI escape string?
I'd use ncurses and a defined set of COLOR_PAIRs: use an enum for the
defined values (it looks like you are already doing this).
(4) How could I make this more easy to use?


Personally, I'd prefer to use an ncurses-based toolkit that provided a
higher-level abstraction of terminal I/O, providing widgets, input
focus, container-based widget alignment and sizing etc.. Essentially,
I mean an object-oriented toolkit after the likes of GTK+/Gtkmm or
Swing.
--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
Jul 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.