Dup Ver Goto 📝

FLTK Examples 01

PT2/lang/python/fltk python fltk does not exist
To
195 lines, 481 words, 4774 chars Page 'Examples_01' does not exist.

Text Display

#!/usr/bin/env python

from fltk import *
import sys
import os

def quit():
  win = Fl.first_window()
  while win := Fl.first_window():
    win.hide()

class MyWindow(Fl_Window):
  def __init__(self,width,height,textsize=14,text="",margin=20):
    super().__init__(width,height)
    coords = (margin,margin,width-2*margin,height-2*margin)
    self.mytext = Fl_Text_Display(*coords)
    self.mytext.textsize(textsize)
    self.bgcolor = fl_rgb_color(0,0,30)
    self.fgcolor = fl_rgb_color(255,255,130)
    self.mytext.textcolor(self.fgcolor)
    self.mytext.color(self.bgcolor)
    self.textbuffer = Fl_Text_Buffer()
    self.textbuffer.text(text)
    self.mytext.buffer(self.textbuffer)
    self.add(self.mytext)
    self.end()
  def handle(self,x):
    match x:
      case 12:
        return self.handlekey()
    return super().handle(x)
  def handlekey(self):
    k = Fl.event_key()
    t = Fl.event_text()
    print("MyWindow","key",k,"text",t)
    match t.lower():
      case "q":
        print("Window Quit")
        quit()
        return 1
    return 0

def main():
  args = sys.argv[1:]
  switches = []
  other = []
  for x in args:
    if x[0] == "-":
      switches.append(x)
    else:
      other.append(x)
  # we pass all switches to the Fl handler,
  # but all other text we want to deal with.
  argv = [sys.argv[0]] + switches

  # configure using environment variables
  # rather than having a more elaborate arg processor
  geom = os.getenv("GEOMETRY","400,300")
  margin = os.getenv("MARGIN","20")
  textsize = os.getenv("TEXTSIZE","14")

  # validate env variables for sanity
  try:
    width, height = [ int(x) for x in geom.split(",") ]
  except ValueError:
    print("Bad GEOMETRY",geom)
    exit(1)
  try:
    textsize = int(textsize)
  except ValueError:
    print("Bad TEXTSIZE",textsize)
    exit(1)
  try:
    margin = int(margin)
    if margin < 0:
      raise ValueError()
    coords = (margin,margin,width-2*margin,height-2*margin)
    if coords[2] <= 0 or coords[3] <= 0:
      raise ValueError()
  except ValueError:
    print("Bad MARGIN",margin)
    exit(1)

  # the text that will be displayed:
  # the result of concatenating command line args
  # one per line and any text piped in.
  if not sys.stdin.isatty():
    other.append(sys.stdin.read())
  text = "\n".join(other)

  window = MyWindow(width,height,textsize=textsize,text=text,margin=margin)
  window.show(argv)
  Fl.run()
  print("Finished")

if __name__ == "__main__":
  main()

A similar C++ version is this. It also illustrates how to turn naked pointers of old style C++ into std::unique_ptrs.

/*
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 <stdio.h>
#include <unistd.h>

#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() {

    }
    MyWindow(int width, int height, int margin) : 
      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));
      end();
    }
    void text(std::string txt) {
      m_text_buffer->text(txt.c_str());  
    }
    int handle(int x) {
      switch(x) {
        case 12:
          return handlekey();
      }
      return 0;
    }
    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;
}

int main(int argc, char **argv) {
  std::string text = get_text();
  std::unique_ptr<MyWindow> window = std::make_unique<MyWindow>(400,400,10);
  window->text(text);
  window->show(argc, argv);
  return Fl::run();
}