From: zenner@dfki.uni-sb.de (Frank Zenner)
Newsgroups: comp.windows.interviews
Subject: updating glyphs without user-interaction
Date: 18 Dec 1992 18:10:26 +0100
Organization: DFKI - German Research Center for AI
Distribution: world
NNTP-Posting-Host: gs-elc6.dfki.uni-sb.de

Hi everybody !!!!!


I want to write the following program:
A circle (bullet) should moving over the screen, 
changing it's direction when bumping against window
borders.

The problem is the following:
I cannot force InterViews to update a glyph without an user
interaction. 

I came to that point:
Whenever the button is pressed, the movement makes one single
step. But the movement which should happen inside a simple
for-loop are ignored.
 
When examining the program, you should also know, that
as long as you have not been inside the main window area
(the InputHandler glyph) with your mouse pointer,
nothing will happen at all.

I guess that I am missing the knack to unvalidate the
glyphs.

Further questions:
  1)  Why I have to move inside the window for getting
      the update. What happens then ?
  2)  What is LayoutKit::overlay


Thank you for the time.
I appreciate every hint!!!!

When I have the solution, I will post this little demo
program.


Here is the Program.
It should compile with the Makefile's coming with the
simple InterViews examples:




#include <IV-look/kit.h>
#include <InterViews/background.h>
#include <InterViews/brush.h>
#include <InterViews/canvas.h>
#include <InterViews/color.h>
#include <InterViews/layout.h>
#include <InterViews/session.h>
#include <InterViews/window.h>
#include <InterViews/style.h>
#include <InterViews/target.h>
#include <InterViews/event.h>
#include <InterViews/hit.h>
#include <IV-X11/xcanvas.h>   // for CanvasRep
#include <stdio.h>


   Coord cx_;   // center coordinates for bullet
   Coord cy_;



int debug=0;

void dump(char* s) {
  if (debug==1) {
    printf("\n%s",s);
    fflush(stdout);
  };
};


class Bullet : public Glyph {
public:
  Bullet(Coord radius, const Color*, const Brush*);
  virtual ~Bullet();
  virtual void request(Requisition&) const;
  virtual void allocate(Canvas*, const Allocation&, Extension&);
  virtual void draw(Canvas*, const Allocation&) const;

  void getExtend(Coord& l, Coord& b, Coord& r, Coord& t) const;
  void move(Canvas* c, const Allocation& a) const;
  void draw_gs(Canvas* c, const Allocation& a) const;
    
private:
    Coord radius_;
//    Coord  cx_, cy_;  // center x,y
    const Color* color_;
    const Brush* brush_;
};

Bullet::Bullet(Coord r, const Color* c, const Brush* b) {
  radius_ = r;
    cx_=0;
    cy_=0;
    Resource::ref(c);
    color_ = c;
    Resource::ref(b);
    brush_ = b;
}

Bullet::~Bullet() {
    Resource::unref(color_);
    Resource::unref(brush_);
}

void Bullet::request(Requisition& req) const {
    Coord w = brush_->width();
    Coord diameter = radius_ + radius_;//  + w + w;
    Requirement rx(diameter, 0, 0, 0);
    Requirement ry(diameter, 0, 0, 0);
    req.require(Dimension_X, rx);
    req.require(Dimension_Y, ry);
}

void Bullet::getExtend(Coord& l, Coord& b, Coord& r, Coord& t) const {
  Coord tol=3;
  l=cx_-radius_/2-tol;   // speed enhancement possible
  b=cy_-radius_/2-tol;
  r=cx_-radius_/2+tol;
  t=cy_-radius_/2+tol;
}


void Bullet::move(Canvas* c,const Allocation& a) const {
  dump("in void Bullet::move(Canvas* c)");
  Coord l,b,r,t;
  getExtend(l,b,r,t);
  c->damage(l,b,r,t);
  static Coord dx=2;
  static Coord dy=2;
  if (cx_>=400) {
    dx=-5;
  };
  if (cy_>=300) {
    dy=-5;
  };
  if (cx_<=5) {
    dx=5;
  };
  if (cy_<=5) {
    dy=5;
  };

  cx_+=dx;
  cy_+=dy;
  getExtend(l,b,r,t);
  c->damage(l,b,r,t);
  CanvasRep& rep=*c->rep();
  CanvasDamage& cd=rep.damage_;
  rep.start_repair();
  draw_gs(c,a);
  rep.finish_repair();
}


void Bullet::draw_gs(Canvas* c, const Allocation& a) const {
  debug=1;
  dump("in void Bullet::draw_gs");
  debug=0;
  const Coord p0 = 1.00000000 * radius_;
  const Coord p1 = 0.89657547 * radius_; // cos 30 * sqrt(1 + tan 15 * tan 15)
  const Coord p2 = 0.70710678 * radius_; // cos 45
  const Coord p3 = 0.51763809 * radius_; // cos 60 * sqrt(1 + tan 15 * tan 15)
  const Coord p4 = 0.26794919 * radius_;   // tan 15
  c->new_path();
  c->move_to(cx_+p0, cy_);
  c->curve_to(cx_+p2, cy_+p2, cx_+p0, cy_+p4, cx_+p1, cy_+p3);
  c->curve_to(cx_, cy_+p0, cx_+p3, cy_+p1, cx_+p4, cy_+p0);
  c->curve_to(cx_-p2, cy_+p2, cx_-p4, cy_+p0, cx_-p3, cy_+p1);
  c->curve_to(cx_-p0, cy_, cx_-p1, cy_ + p3, cx_-p0, cy_+p4);
  c->curve_to(cx_-p2, cy_-p2, cx_-p0, cy_-p4, cx_-p1, cy_-p3);
  c->curve_to(cx_, cy_-p0, cx_-p3, cy_-p1, cx_-p4, cy_-p0);
  c->curve_to(cx_+p2, cy_-p2, cx_+p4, cy_-p0, cx_+p3, cy_-p1);
  c->curve_to(cx_+p0, cy_, cx_+p1, cy_-p3, cx_+p0, cy_-p4);
  c->close_path();
  c->stroke(color_, brush_);  
}

void Bullet::allocate(Canvas* c, const Allocation& a, Extension& ext) {
    ext.merge(c, a);
}

void Bullet::draw(Canvas* c, const Allocation& a) const {
  dump("inBullet::draw");
  move(c,a);  
}


class MyView : public InputHandler {
public:
  MyView(char* name, Style* style,
	 Coord length, Coord width);
  virtual ~MyView();

  virtual void request(Requisition&) const;
  virtual void allocate(Canvas*, const Allocation&, Extension&);
  virtual void draw(Canvas*, const Allocation&) const;

  void insertGlyph(Glyph* glyph);
  void step();  

  Coord length_, width_;
  const Color* color_;
  const Brush* brush_;

};

MyView::MyView(char *name, Style* style,
	       Coord length, Coord width) 
  :InputHandler(nil,style) {
  length_ = length;
  width_=width;
}

MyView::~MyView() {
    Resource::unref(color_);
    Resource::unref(brush_);
}

void MyView::request(Requisition& req) const {
    Requirement rx(length_, 0, 0, 0);
    Requirement ry(width_, 0, 0, 0);
    req.require(Dimension_X, rx);
    req.require(Dimension_Y, ry);
}

void MyView::allocate(Canvas* c, const Allocation& a, Extension& ext) {
    ext.merge(c, a);
}

void MyView::draw(Canvas* c, const Allocation& a) const {
  dump("inMyView::draw");
  Glyph* body__=body();
  if (body__!=nil) {
    body()->draw(c,a);
  }

}

void MyView::insertGlyph(Glyph* glyph) {
  body(new Target(glyph,TargetPrimitiveHit));
}


void MyView::step() {
  dump("in MyView::step()");
  redraw();
};

class Manip {
public:
  Manip(MyView *view);
  void action1();
  MyView *view_;
};

Manip::Manip(MyView *view) {
  view_=view;
}
  

void Manip::action1() {
  dump("in Manip::action1()");
  for (int i=1; i<=10;i++) {
    printf("\nin loop");
    view_->step();
  }
}



declareActionCallback(Manip)
implementActionCallback(Manip)



int main(int argc, char** argv) {
  Session* session = new Session("Himom", argc, argv);
  WidgetKit& kit = *WidgetKit::instance();
  const LayoutKit& layout = *LayoutKit::instance();
  Style* style = session->style();


  Bullet* bullet1=new Bullet(10,kit.foreground(),new Brush(1.0));
  MyView* myView=new MyView("test",style,500,500);
  myView->insertGlyph(bullet1);

  Manip *manip=new Manip(myView);

  session->run_window(
    new ApplicationWindow(
      new Background(
        layout.vbox(
  	  kit.push_button("Button1", new ActionCallback(Manip)(manip, &Manip::action1)),
          layout.vbox(
            kit.inset_frame(myView),
          ),
        ),
	  kit.background()
      )
    )
  );
}
Newsgroups: comp.windows.interviews