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

Reply via email to