Hi Stan,
let me thank you again, I must state that for me - being primarily hardware
eng. and c++ autodidact (since about 6 weeks, since I found fltk) your code is
way over my head. It really draws very fast.
Anyway I'm reading it now trying to understand it better, I added two scale()
calls to it (see below) because zoom-out did not redraw the whole area.
Thanks,
Jens
-------------------------------------
void zoomin()
{
gzoom = std::min(gzoom * zoom_factor, MAXSIZE);
std::cout << gzoom << std::endl;
scale();
range();
redraw();
}
void zoomout()
{
gzoom = std::max(gzoom / zoom_factor, 1);
std::cout << gzoom << std::endl;
scale();
range();
redraw();
}
> Thanks very much Stan,
>
> I'll take a look at your example and will see how it works.
>
> Regards scrolling I'm not good enough as a programmer to re-implement the
> scrolling widget that's why in the meantime I went ahead with my previous
> code each cell is one object using real cell information (size,
> position, cell-name, cell-instance).
>
> Now it as auto-highlight of the design hierarchy, clicking on a cells shows
> the name etc.
>
> During my trials I had deeper look into FL_Group.cxx and noticed that in the
> event handler always all children are scanned in the event loop even if they
> are disactivated.
>
> This is what's really slowing down my approach! (which otherwise is quite
> handy because I can directly use the FLTK widgets as they are).
>
> Now my question would be,
> -------------------------
>
> Is it possible to change the FLTK event architecture by removing the
> disactivated children from the event-loop but still leave them in the drawing
> loop.
>
>
> Are there intentions to do something like this in FLTK2?
>
> Jens
>
>
>
>
>
> > > Well, just or "fun" I threw together a hack of Jens program that
> > > stores the "ASIC cells" in a separate list, not as fltk widgets, then
> > > scales and renders them only in the draw method.
> > >
> > [..]
> >
> > > Unfortunately, it doesn't seem much (if any) quicker...
> >
> > I had some time on my hands, so I thought I'd see if I could
> > make this work. Here's a further hack -- it takes awhile to
> > start up, but seems responsive enough after that. Adding
> > scrolling would be cool ....
> >
> > Best,
> > Stan
> >
> > //////////////////////////////////////////////////////////////////////
> > #include <FL/Fl.H>
> > #include <FL/fl_draw.H>
> > #include <FL/Fl_Double_Window.H>
> > #include <FL/Fl_Box.H>
> > #include <FL/Fl_Button.H>
> > #include <vector>
> > #include <functional>
> > #include <algorithm>
> >
> > struct Cell {
> > int x, y, w, h;
> > int xm, ym;
> > int c_;
> > Cell(int X, int Y, int W, int H)
> > : x(X), y(Y), w(W), h(H), c_(FL_WHITE)
> > , xm(X+W), ym(Y+H)
> > {;}
> > };
> >
> > typedef std::vector<Cell*> Vector;
> > typedef Vector::iterator Iterator;
> >
> > /////////////////////////////////////////////////////////////////////////////////////
> >
> > class cell_box : public Fl_Box {
> > public:
> > cell_box(int X, int Y, int W, int H, const char *L=0)
> > : Fl_Box(X,Y,W,H,L)
> > , gzoom(100)
> > , sorted(true)
> > {
> > scale();
> > }
> >
> > ~cell_box() {;} // Antipodean destructor, in Ian's honor
> >
> > void add(Cell* cell)
> > {
> > byX.push_back(cell);
> > byY.push_back(cell);
> > sorted = false;
> > }
> >
> > void reserve(Vector::size_type n)
> > { byX.reserve(n); byY.reserve(n); }
> >
> > static int diex() { return diex_; }
> > static int diey() { return diey_; }
> >
> > void zoomin()
> > {
> > gzoom = std::min(gzoom * zoom_factor, MAXSIZE);
> > range();
> > redraw();
> > }
> >
> > void zoomout()
> > {
> > gzoom = std::max(gzoom / zoom_factor, 1);
> > range();
> > redraw();
> > }
> >
> > private:
> > void scale();
> > void draw();
> > void range();
> >
> > static int const MAXSIZE;
> > static int const diex_;
> > static int const diey_;
> > static int const zoom_factor;
> >
> > int gzoom;
> > int view_x;
> > int view_y;
> > int vx2;
> > int vy2;
> > int min_x;
> > int max_x;
> > int min_y;
> > int max_y;
> > bool sorted;
> >
> > // Cells sorted by x / by y
> > Vector byX;
> > Vector byY;
> >
> > // Cells in visible x range / y range
> > std::pair<Iterator, Iterator> xrange;
> > std::pair<Iterator, Iterator> yrange;
> > };
> >
> > int const cell_box::MAXSIZE = 32768; // zoom limit is ok for the moment
> > int const cell_box::diex_ = 9408000;
> > int const cell_box::diey_ = 9408000; // real world chip size
> > int const cell_box::zoom_factor = 2;
> >
> > /////////////////////////////////////////////////////////////////////////////////////
> >
> > // Cell < Cell by x
> > struct LessX : public std::binary_function<Cell*, Cell*, bool> {
> > bool operator()(Cell const* lhs, Cell const* rhs) const
> > { return lhs->x < rhs->x; }
> > };
> > // Cell < Cell by y
> > struct LessY : public std::binary_function<Cell*, Cell*, bool> {
> > bool operator()(Cell const* lhs, Cell const* rhs) const
> > { return lhs->y < rhs->y; }
> > };
> > // Cell horiz location < i?
> > struct ByX : public std::binary_function<Cell*, int, bool> {
> > bool operator()(Cell const* e, int i)
> > { return e->xm < i; }
> > };
> > // Cell vert location < i?
> > struct ByY : public std::binary_function<Cell*, int, bool> {
> > bool operator()(Cell const* e, int i)
> > { return e->ym < i; }
> > };
> >
> > std::pair<Iterator, Iterator>
> > betweenX(Iterator begin, Iterator end, int lo, int hi)
> > {
> > Iterator lb = std::lower_bound(begin, end, lo, ByX());
> > Iterator ub = lb;
> > for( ; ub != end && (*ub)->x < hi; ++ub) {;}
> > return std::make_pair(lb, ub);
> > }
> > std::pair<Iterator, Iterator>
> > betweenY(Iterator begin, Iterator end, int lo, int hi)
> > {
> > Iterator lb = std::lower_bound(begin, end, lo, ByY());
> > Iterator ub = lb;
> > for( ; ub != end && (*ub)->y < hi; ++ub) {;}
> > return std::make_pair(lb, ub);
> > }
> >
> > /////////////////////////////////////////////////////////////////////////////////////
> > void
> > cell_box::scale()
> > {
> > view_x = diex_ / gzoom;
> > view_y = diey_ / gzoom;
> > vx2 = view_x / 2;
> > vy2 = view_y / 2;
> > min_x = diex_ / 2 - vx2;
> > max_x = diex_ / 2 + vx2;
> > min_y = diey_ / 2 - vy2;
> > max_y = diey_ / 2 + vy2;
> > }
> >
> > void
> > cell_box::range()
> > {
> > xrange = betweenX(byX.begin(), byX.end(), min_x, max_x);
> > yrange = betweenY(byY.begin(), byY.end(), min_y, max_y);
> > }
> > void cell_box::draw(void)
> > {
> > scale();
> >
> > if(!sorted) {
> > std::sort(byX.begin(), byX.end(), LessX());
> > std::sort(byY.begin(), byY.end(), LessY());
> > range();
> > sorted = true;
> > }
> >
> > // how big is our actual viewport?
> > int wo = w();
> > int ho = h();
> > double xscale = (double)view_x / (double)wo;
> >
> > // which cells are visible?
> >
> > // copy those in x-range and y-range
> > Vector x_contents(xrange.first, xrange.second);
> > Vector y_contents(yrange.first, yrange.second);
> >
> > // sort them
> > std::sort(x_contents.begin(), x_contents.end());
> > std::sort(y_contents.begin(), y_contents.end());
> >
> > // the intersection is the visible ones
> > Vector visible;
> > std::insert_iterator<Vector> visible_inserter(visible,
> > visible.begin());
> > std::set_intersection(
> > x_contents.begin(), x_contents.end(),
> > y_contents.begin(), y_contents.end(),
> > visible_inserter
> > );
> >
> > // ensure the view area is clipped and cleared
> > fl_push_clip(x(), y(), wo, ho);
> > fl_color(FL_RED);
> > fl_rectf(x(), y(), wo, ho);
> >
> > for(Iterator i = visible.begin(); i != visible.end(); ++i) {
> > Cell* cp = *i;
> > int xd = (int)((double)(cp->x - min_x) / xscale);
> > int yd = (int)((double)(cp->y - min_y) / xscale);
> > int wd = (int)((double)cp->w / xscale);
> > int hd = (int)((double)cp->h / xscale);
> > fl_color(cp->c_);
> > fl_rectf(xd, yd, wd, hd);
> > fl_color(FL_BLACK);
> > fl_rect(xd, yd, wd, hd);
> > }
> > fl_pop_clip();
> >
> > } /* end of draw() method */
> > static void zoomincb(Fl_Widget*, void* v)
> > {
> > static_cast<cell_box*>(v)->zoomin();
> > }
> >
> > static void zoomoutcb(Fl_Widget*, void* v)
> > {
> > static_cast<cell_box*>(v)->zoomout();
> > }
> >
> > ////////////////////////
> > int main()
> > {
> > // Create the fltk framework
> > Fl_Double_Window win(800, 800);
> > cell_box cell_view(5, 5, win.w()-10, win.h()-60);
> > Fl_Box box(0,win.h()-50,win.w(),50);
> > Fl_Button zoomin(0,win.h()-40,100,35,"Zoom in");
> > Fl_Button zoomout(120,win.h()-40,100,35,"Zoom out");
> > win.end();
> >
> > zoomin.callback(zoomincb, &cell_view);
> > zoomout.callback(zoomoutcb, &cell_view);
> > win.resizable(&cell_view);
> >
> > // Make the random list of test cells
> > cell_view.reserve(2000000);
> > int diex = cell_view.diex();
> > int diey = cell_view.diey();
> > int x = 0, y = 0, w = 0, h = 0;
> > for(x = 0; x < diex; x = x+w) {
> > // 6000 ~ 1.2 Mio components, 600 ~ 11000 components
> > w = (1 + (int)(10.0*rand()/(RAND_MAX+1.0))) * diex/6000;
> > for(y = 0; y < diey; y = y+h) {
> > // 6000 ~ 1.2 Mio components, 600 ~ 11000 components
> > h = (1 + (int)(10.0*rand()/(RAND_MAX+1.0))) * diey/6000;
> > cell_view.add(new Cell(x, y, w, h));
> > }
> > }
> >
> > win.show();
> > return Fl::run();
> > }
> >
>
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk