FLTK logo

Re: passing things from terminal to GUI

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: passing things from terminal to GUI Greg Ercolano Jun 02, 2007  
 
> 	I'll try to follow up with a rewrite of your app, so that you can get
> 	an idea of how it should be laid out. Shouldn't be hard.

   I rewrote it -- you may not recognize it, but this is more likely
   how it should be laid out.. this approach will 'scale' to larger apps.

   Notice how everything is in the EditorWindow class now.. this
   way all the methods/callbacks can access all the data it needs
   without it being global.

   This means you can easily create several instances of EditorWindow,
   each with its own commands that can be running concurrently.

   Notes on what I removed (for brevity):

       > I wasn't sure what the multibrowser was for, so I took it out.

       > I also removed the file load stuff, because it seemed unrelated
         to the problem. Note that Fl_Text_Buffer has a loadfile() method,
         so you can use that to load the editor with a text file, rather
         than writing it yourself, though maybe you needed something custom,
         I didn't look.

       > I rewrote the menu code a bit.. I dislike using that static menu
         array stuff, and prefer using the menubar->add() approach.

   Study the design of this, and see if you can see why it has
   been laid out this way. Putting all the variables into the class
   cleans up all the variable scoping, so that everything has access
   to what it needs, cleanly, without all those nasty globals.

   Follow up with questions if you need to, but I think if you look
   at it carefully, you'll get it.

   The nasty globals in the original demo app were just to keep
   the demo simple. It's assumed the reader is familiar with the
   mechanics of C++, and after reading the example, can re-scope the
   the variables as they please.

   HTH.

---- snip

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#ifdef _WIN32
#include <windows.h>
#define popen  _popen
#define pclose _pclose
#else
#include <unistd.h>
#endif
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Editor.H>
#include <FL/Fl_Window.H>

class EditorWindow : public Fl_Double_Window {
    // Menubar
    Fl_Menu_Bar *menubar;

    // File editor
    Fl_Text_Editor *file_edit;
    Fl_Text_Buffer *file_buff;

    // Console editor
    Fl_Text_Editor *console_edit;
    Fl_Text_Buffer *console_buff;

    // Popen stuff
    FILE *fp;
    char command[512];

    // DATA CALLBACK: Handle reading data from running command
    void HandleFD() {
        static char s[1024];
        if ( fgets(s, sizeof(s)-1, fp) == NULL ) {
            Fl::remove_fd(fileno(fp));
            pclose(fp);
            fp = 0;
            console_buff->append("--- COMMAND COMPLETED\n");
        } else {
            console_buff->append(s);
        }
    }
    static void HandleFD_CB(int, void *userdata) {
        EditorWindow *ewin = (EditorWindow*)userdata;
        ewin->HandleFD();                               // avoids having to do ewin->xxx to access vars
    }
    // MENU CALLBACK: Build command
    static void MakeCommand_CB(Fl_Widget*, void*userdata) {
        EditorWindow *ewin = (EditorWindow*)userdata;
        strcpy(ewin->command, "netstat -an 2>&1");      // create the command
    }
    // MENU CALLBACK: Start command running
    void RunCommand() {
        if ( fp != 0 ) return;                          // command already running? ignore
        console_buff->text("");                         // clear window
        if ( command[0] == 0 ) {                        // no command? complain
            console_buff->text("No command specified");
            return;
        }
        fp = popen(command, "r");                       // start command running..
        if ( fp == NULL ) {                             // Failed? show error
            console_buff->append("ERROR: popen: ");
            console_buff->append(strerror(errno));
        } else {                                        // Worked? setup handler
            Fl::add_fd(fileno(fp), HandleFD_CB, (void*)this);
        }
    }
    // MENU CALLBACK: Start command running
    static void RunCommand_CB(Fl_Widget*, void*userdata) {
        EditorWindow *ewin = (EditorWindow*)userdata;
        ewin->RunCommand();                             // avoids having to do ewin->xxx to access vars
    }

public:
    // Ctor
    EditorWindow(int w, int h, const char* t) : Fl_Double_Window(w, h, t) {
        // Create menu bar
        menubar = new Fl_Menu_Bar(0, 0, w, 25);
        menubar->add("&File/Make Command", FL_CTRL+'s', MakeCommand_CB, (void*)this);
        menubar->add("&File/Run",          FL_CTRL+'r', RunCommand_CB,  (void*)this);

        // Create file editor
        file_edit = new Fl_Text_Editor(0, 40, w, 260, "File Editor");
        file_buff = new Fl_Text_Buffer();
        file_edit->buffer(file_buff);
        file_edit->textfont(FL_COURIER);

        // Create console editor
        console_edit = new Fl_Text_Editor(0, 320, w, 260, "Console Output");
        console_buff = new Fl_Text_Buffer();
        console_edit->buffer(console_buff);
        console_edit->textfont(FL_COURIER);

        // Popen stuff
        fp = NULL;
        command[0] = 0;

        end();
        resizable(this);
    }
    ~EditorWindow() {
    }
};

int main(int argc, char **argv) {
    EditorWindow *ewin = new EditorWindow(600, 600, "Test");
    ewin->show();
    return(Fl::run());
}

Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.