This allows width, height, margin, fontname and fontsize to be specified via environment variables.
Fltk uses an integer-indexed font table. Set the font name with Fl::set_font(43,"Comic Sans").
/*
build with
g++ -o fl_text_display fl_text_display.cpp -lfltk -lX11 -lm
*/
// for unique_ptr and make_unique
#include <memory>
// for cout and cin
#include <iostream>
// Needed for seeing if stdin is a pipe or a tty
#include <cstdio>
#include <unistd.h>
// Needed for atoi() and getenv()
#include <cstdlib>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Text_Buffer.H>
class MyWindow : public Fl_Window {
protected:
std::unique_ptr<Fl_Text_Display> m_text_display;
std::unique_ptr<Fl_Text_Buffer> m_text_buffer;
int m_width;
int m_height;
int m_margin;
public:
virtual ~MyWindow() {
m_text_display->buffer(0);
}
MyWindow(int width, int height, int margin, int fontsize = 14, Fl_Font font = 0) :
Fl_Window(width,height) {
m_width = width;
m_height = height;
m_margin = margin;
if(
(2 * m_margin) > m_width ||
(2 * m_margin) > m_height
) {
m_margin = 0;
}
m_text_display = std::make_unique<Fl_Text_Display>(m_margin,m_margin,m_width-2*m_margin,m_height-2*m_margin);
m_text_buffer = std::make_unique<Fl_Text_Buffer>();
m_text_display->buffer(*m_text_buffer);
m_text_display->textcolor(fl_rgb_color(255,255,130));
m_text_display->color(fl_rgb_color(0,0,30));
m_text_display->textsize(fontsize);
m_text_display->textfont(font);
end();
}
void text(std::string txt) {
m_text_buffer->text(txt.c_str());
}
int handle(int x) {
switch(x) {
case 12:
if( handlekey() ) return 1;
break;
}
return Fl_Window::handle(x);
}
int handlekey() {
switch(Fl::event_key()) {
case 'q':
case 'Q':
quit();
return 1;
}
return 0;
}
void quit() {
Fl_Window* win;
while( win = Fl::first_window() ) {
win->hide();
}
}
private:
};
std::string get_text() {
if( isatty(fileno(stdin)) ) return std::string();
std::istreambuf_iterator<char> begin(std::cin), end;
std::string buf(begin, end);
return buf;
}
void getdims(int &width, int &height, int &margin) {
width = 800, height = 500, margin = 0;
char *val;
if( val = getenv("WIDTH") ) {
int x = atoi(val);
if( x < 50 || x > 1800 ) {
std::cout << "WIDTH out of range: " << val << "\n";
} else {
width = x;
}
}
if( val = getenv("HEIGHT") ) {
int x = atoi(val);
if( x < 50 || x > 700 ) {
std::cout << "HEIGHT out of range: " << val << "\n";
} else {
height = x;
}
}
if( val = getenv("MARGIN") ) {
int x = atoi(val);
int iw = width - 2*x;
int ih = height - 2*x;
if( iw < 50 || ih < 50 ) {
std::cout << "MARGIN out of range: " << val << "\n";
} else {
margin = x;
}
}
}
void getfont(std::string &fontname, int &fontsize) {
fontsize = 14;
fontname = "Hack Nerd Font Mono";
char* val;
if( val = getenv("FONTNAME") ) {
fontname = val;
}
if( val = getenv("FONTSIZE") ) {
int x = atoi(val);
if( x < 8 || x > 50 ) {
std::cout << "FONTSIZE out of range: " << val << "\n";
} else {
fontsize = x;
}
}
}
int main(int argc, char **argv) {
int width, height, margin;
getdims(width, height, margin);
std::string fontname;
int fontsize;
getfont(fontname,fontsize);
Fl::set_font(20,fontname.c_str());
std::string text = get_text();
std::unique_ptr<MyWindow> window = std::make_unique<MyWindow>(width,height,margin,fontsize,20);
window->text(text);
window->show(argc, argv);
return Fl::run();
}