Dup Ver Goto 📝

Text View Example

PT2/lang/cpp/fltk cpp fltk does not exist
To
160 lines, 488 words, 3879 chars Page 'TextViewExample_01' does not exist.

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();
}