🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.windows.interviews
2 messages
2 total messages Started by Frank Zenner Fri, 18 Dec 1992 17:10
updating glyphs without user-interaction
#1367
Author: Frank Zenner
Date: Fri, 18 Dec 1992 17:10
308 lines
7841 bytes
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()
      )
    )
  );
}
Re: updating glyphs without user-interaction
#1375
Author: Mike Howard
Date: Sat, 19 Dec 1992 05:42
32 lines
1771 bytes
In article <1gt0m2INNi71@godard.dfki.uni-sb.de>, zenner@dfki.uni-sb.de
(Frank Zenner) writes: 
|> The problem is the following: 
|> I cannot force InterViews to update a glyph without an user 
|> interaction.

Try Dispatcher class to update your glyph.  There is a man page on it.
You can use a timer to generate the position update.  Look at the
morpher example (iv/src/examples/morpher/morpher.c) and check out
Morpher::execute(), where they use:

Dispatcher::instance()->startTimer(0,100000,_m_impl->_callback);

where _callback is:

new IOCallback(Morpher)(this, &Morpher::tick)

----------
As far as the problem with the update, I'm a novice, too, but I don't
see why you need a canvas as well as a glyph.  Seems to me you could
just declare a bullet glyph with a 400x400 requisition, and put it in
a patch.  Bullet::draw() has a Canvas and Allocation as parameters, so
it can draw itself on it's canvas.  A glyph's draw operation is called
implicitly when you call patch->redraw().  I create the Patch in
main(), giving it the glyph.  Then I pass the patch into storage in
the glyph using a glyph->patch( Patch* patch ) sort of access routine.
Then my glyph is always able to redraw itself.  Possibly your 2
canvases are complicating things.

I'll be interested to see your results

Mike Howard, Hughes Research Labs
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads