|
> The individual 'incremental method you mentioned would be of
> interest to me for insight also, if you would like to post it, thanks.
OK, see below.
Sorry to everyone who's seen this before, I am sure I have posted it but
could not find it in the forums...
It incrementally renders random coloured lines to an offscreen surface
and then displays a view of that in a window.
The rendered "canvas" can be dragged around the view window, and the
view is resizable.
Enjoy...
-----------------
/***********************************************************************
******/
// fltk-config --compile offscreen-demo.cxx
/* Standard headers */
#include <stdlib.h>
#include <time.h> // use time() in random code below
/* Fltk headers */
#include <Fl/Fl.h>
#include <FL/Fl_Double_Window.H>
#include <FL/x.H>
#include <Fl/Fl_Box.H>
#include <Fl/fl_draw.h>
// The main window for the demo
static Fl_Double_Window *main_window = 0;
// The offscreen surface
static Fl_Offscreen oscr = 0; // the surface
static int os_w = 0, os_h = 0; // the surface's dimensions
/***********************************************************************
******/
/* This class provides a view into the offscreen surface */
class oscr_box : public Fl_Box {
void draw();
int handle(int event);
protected:
int x_old, y_old; /* previous x,y during a drag operation */
int drag_state; /* non-zero if a drag is in progress */
int page_x, page_y; /* current view position */
public:
oscr_box(int x, int y, int w, int h);
};
/***********************************************************************
******/
/* Constructor */
oscr_box::oscr_box(int x, int y, int w, int h) : Fl_Box(x,y,w,h){
x_old = y_old = 0;
drag_state = 0;
page_x = page_y = 750;
} // Constructor
/***********************************************************************
******/
void oscr_box::draw() {
int wd = w();
int ht = h();
int xo = x();
int yo = y();
// first clear out the view to a flat grey - this is
// redundant if we know the offscreen will fill the view
fl_color(fl_gray_ramp(19));
fl_rectf(xo, yo, wd, ht);
// now draw the view
if(oscr) { // offscreen exists
// blit the required view from the offscreen onto the
box
fl_copy_offscreen(xo, yo, wd, ht, oscr, page_x, page_y);
}
else { // create the offscreen
// some platforms seem to need a context to base the
offscreen
// on, so make the main window current here...
main_window->make_current();
// set the dimensions for the offscreen surface
os_w = 2000; os_h = 2000;
oscr = fl_create_offscreen(os_w, os_h);
// did the create fail?
if(!oscr) {
// Fail - clear the dimensions out again
os_w = os_h = 0;
}
}
} // draw method
/***********************************************************************
******/
int oscr_box::handle(int ev) {
// call the base class event handler
int ret = Fl_Box::handle(ev);
// if there is no offscreen surface, we can return now
if(!oscr) return ret;
// Handle dragging of visible area - if a valid context exists.
// All sorts of editor stuff could be added here... later...
switch(ev) {
case FL_ENTER:
main_window->cursor(FL_CURSOR_MOVE);
ret = 1;
break;
case FL_LEAVE:
main_window->cursor(FL_CURSOR_DEFAULT);
ret = 1;
break;
case FL_PUSH:
x_old = Fl::event_x_root();
y_old = Fl::event_y_root();
drag_state = 1; // drag
ret = 1;
break;
case FL_DRAG:
if(drag_state == 1) { // dragging is active
// how far did we drag since last event?
int x_new = Fl::event_x_root();
int y_new = Fl::event_y_root();
int xoff = x_old - x_new;
int yoff = y_old - y_new;
x_old = x_new;
y_old = y_new;
// update the view position by the drag amount
page_x += xoff;
page_y += yoff;
// check the page bounds and clamp at edges
if(page_x < -w()) page_x = -w();
else if(page_x > os_w) page_x = os_w;
if(page_y < -h()) page_y = -h();
else if(page_y > os_h) page_y = os_h;
// trigger a redraw of the view because we moved
redraw();
}
ret = 1;
break;
case FL_RELEASE:
drag_state = 0; // not dragging any more
ret = 1;
break;
default:
break;
}
return ret;
} // handle
/***********************************************************************
******/
static oscr_box *os_box = 0; // a widget to view the offscreen with
/***********************************************************************
******/
static void oscr_drawing (void) {
Fl_Color col;
static int icol = 56; // a random colour on the ramp
static int ox = 1000, oy = 1000; // somewhere in the offscreen
area
static int iters = 3456; // more than 1024...
if(!oscr) return; // nothing to do here...
fl_begin_offscreen(oscr); /* Open the offscreen context for
drawing */
// for the demo, we "reset" the offscreen periodically
if(iters > 1024) {
fl_color(FL_WHITE);
fl_rectf(0, 0, os_w, os_h);
iters = 0;
}
iters++;
// pick a random colour to draw with
icol++; if(icol > 255) icol = 56;
col = (Fl_Color)icol;
fl_color(col); // set the colour
// pick a random position
int rnd = rand();
double drx = (double)os_w * (double)rnd / (double)RAND_MAX;
rnd = rand();
double dry = (double)os_h * (double)rnd / (double)RAND_MAX;
// pick a random line thickness
rnd = rand();
double drt = 4.0 * (double)rnd / (double)RAND_MAX;
// draw a line from the old point to the new end point
int ex = (int)drx;
int ey = (int)dry;
// draws a solid line of thickness drt
fl_line_style(FL_SOLID, (int)drt);
fl_line(ox, oy, ex, ey);
// old point moved to new end point
ox = ex; oy = ey;
fl_end_offscreen(); // close the offscreen context
} // oscr_drawing
/***********************************************************************
******/
static void oscr_anim(void *) {
if(oscr) { // offscreen exists, draw something
oscr_drawing();
}
// request a redraw of the view box
os_box->redraw();
// repeat the animation delay
Fl::repeat_timeout(0.1, oscr_anim);
} // oscr_anim
/***********************************************************************
******/
int main (int argc, char **argv) {
int win_size = 600;
// create the main window
main_window = new Fl_Double_Window(win_size, win_size,
"Offscreen Demo");
main_window->begin();
// a view of the offscreen, inside the main window
os_box = new oscr_box(5, 5, (win_size - 10), (win_size - 10));
main_window->end();
main_window->resizable(os_box);
// show the app
main_window->show(argc, argv);
// seed the random number sequence
srand(time(NULL));
// add a timer to animate the view updates
Fl::add_timeout(0.1, oscr_anim);
// start the fltk loop
return Fl::run();
} // main
/* end of file */
-----------------
SELEX Galileo Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************
[ Direct Link to Message ] | |