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