Greg Ercolano wrote:
>       *Or*, possibly better, just delete all of this:
> 
> ----
>   sleep(1);
>   while (run_make->value() == 1) {
>        sleep(1); frame->redraw(); Fl::flush();}
>   o->activate(); frame->cursor(FL_CURSOR_DEFAULT);
> ----
> 
>       ..so that the function just returns after the
>       Fl::add_fd() so that Fl::run() will take over..

        Here's a complete working program of what I'm recommending
        above, just as a proof of concept.

        I replaced 'make -j4' with a 'ping -c 10 -i 3 localhost' for testing;
        basically pings the localhost 10 times with a 3 second delay between
        each line.. a long enough wait to be able to see if the interface
        isn't being responsive.

        Just hit the 'Run' button and it should gray out, cursor becomes
        a timer, and output flows to the screen.

        Meanwhile, the interface remains responsive while waiting for
        output; you can see this by dragging over the lines.

        You should notice no perceivable problem with the GUI during
        the 3 second prints from ping. (At least not on a unix machine.
        On a windows machine, the interface will likely /not/ be responsive,
        due to the whole issue of Microsoft's select() only supporting sockets,
        not pipes or files)

        When the command finishes, the light goes out, the button re-activates,
        and you can run the command again.

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Multi_Browser.H>
#include <FL/Fl_Light_Button.H>
#include <FL/fl_ask.h>

Fl_Window        *G_win = 0;
Fl_Multi_Browser *G_out = 0;
Fl_Light_Button  *G_but = 0;
FILE             *G_fp  = 0;
const char       *G_cmd = "ping -c 10 -i 3 localhost";  // or "make -j4 .."

void HandleFD(int fd, void *) {
    char results[1024];
    if ( fgets(results, 1023, G_fp) == NULL ) {
        Fl::remove_fd(fileno(G_fp));            // remove fd
        pclose(G_fp); G_fp = 0;                 // close up
        G_win->cursor(FL_CURSOR_DEFAULT);       // normal cursor
        G_but->value(0);                        // button light off
        G_but->activate();                      // reactivate
        return;                                 // back to FLTK
    }
    char *crlf = strchr(results, '\n');
    if ( crlf ) *crlf = 0;
    G_out->add(results);
}

void Run_CB(Fl_Widget*,void*) {
    if ( ( G_fp = popen(G_cmd, "r") ) == NULL ) {
        fl_message("popen failed");
        return;
    }
    // COMMAND RUNNING: DEACTIVATE BUTTON, WAIT CURSOR, ADD_FD
    G_but->deactivate();                        // gray out button
    G_win->cursor(FL_CURSOR_WAIT);              // timer cursor
    G_out->clear();                             // clear output
    Fl::add_fd(fileno(G_fp), HandleFD, 0);      // tell fltk to watch popen() 
for data
    // NOTE: let FLTK handle everything from here
}

int main() {
    G_win = new Fl_Window(720,450);
    G_out = new Fl_Multi_Browser(10,10,700,400);
    G_but = new Fl_Light_Button(600,420,100,20,"Run");
    G_but->tooltip("Runs 10 iterations of ping,\n"
                   "then stops automatically.\n");
    G_but->callback(Run_CB);
    G_win->end();
    G_win->show();
    return(Fl::run());
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to