andrei_c wrote:
> Hy, I ran into some trouble whit a program that is supposed to display the X 
> and Y coordinates of the mouse relative to the widget it's clicked on when 
> the mouse button is pressed.The X and Y coords should be displayed in 2 
> Fl_Output widgets.And the program should even draws a rectangle relative to 
> the coords of the mouse when the button is pressed.

        In your handle() method for FL_PUSH, I added do_callback();
        to tell your callback to be called when the button is pushed.

        Fl_Box is a dumb widget that doesn't make use of callback()
        at all, so the callback was never getting called.

        I made one other change that makes the program better, but
        doesn't change functionality in your case: I rewrote the handle()
        code a bit so that you're not eclipsing events from Fl_Box.

        Before, it was trapping FL_FOCUS and FL_PUSH, but not passing
        those events down to FL_BOX, preventing it from seeing them.
        This isn't good, as Fl_Box might need those events, you never know.

        The way the handle() code is written now, Fl_Box sees all events
        right at the top, and the return value is retained and returned.
        Our code to handle FL_PUSH simply augments the return value.

        Best way to see my changes would be to xdiff (or windiff) the code.

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Box.H>
#include <Fl/Fl_Value_Output.H>
#include <FL/fl_draw.h>

class Canvas : public Fl_Box // a canvas widget to draw and click on
{
  public:
    Canvas( int x, int y, int w, int h, const char *l); // constructor
    ~Canvas() {}; // destructor

    int XC; // stores coordinates of the mouse
    int YC;

    void draw();
    int handle(int event);
};

Canvas::Canvas( int x, int y, int w, int h, const char *l) : Fl_Box( x, y, w, 
h, l)
{
  box(FL_FLAT_BOX);
  color((Fl_Color)255);

  XC = 0; // initializing the variables
  YC = 0;
}

void Canvas::draw() // overriding draw()
{
  Fl_Box::draw();

  fl_push_clip( x(), y(), w(), h() ); // star clipp

  fl_color(FL_BLACK);
  fl_rect( x(), y(), w(), h() ); // draws a contour to look better

  fl_rect(XC,YC,50,20); // draws the rectangle

  fl_pop_clip();
}

int Canvas::handle(int event) // handling events
{
  int ret = Fl_Box::handle(event);      // let box see all events
  switch(event)
  {
    case FL_FOCUS:
      ret = 1;
      break;
    case FL_PUSH:
      XC = Fl::event_x() - x();         // show events relative to canvas's 
coords
      YC = Fl::event_y() - y();         // ""     ""
      redraw();                         // tell canvas to redraw
      do_callback();                    // do the callback we configured 
(defined in Fl_Widget)
      ret = 1;
      break;
  }
  return(ret);
}

struct Data // a simple struct to store the 2 Fl_Outputs to pass both
            // in the same time to the callback
{
  Fl_Value_Output *X_Out;
  Fl_Value_Output *Y_Out;
};

void canvas_cb(Fl_Widget *w, void *v) // the callback from the Canvas widget
{
  Canvas *c = (Canvas*) w;
  Data *outputs = (Data*) v;

  outputs->X_Out->value(c->XC);
  outputs->X_Out->redraw();

  outputs->Y_Out->value(c->YC);
  outputs->Y_Out->redraw();
}

/*************************************************************************/
int main()
{
  Fl_Double_Window *my_win = new Fl_Double_Window(300,350, "Draw mouse coords");
  my_win->begin();

    Canvas my_canvas(20,20,260,260,0);
    Fl_Value_Output x_coord(30,290,40,20,"X");
    Fl_Value_Output y_coord(30,320,40,20,"Y");

    Data xy_data;
    xy_data.X_Out = &x_coord; // asign the adresses
    xy_data.Y_Out = &y_coord;

    my_canvas.when(FL_PUSH); // just to make shore the callback happens
    my_canvas.callback(canvas_cb, &xy_data);

  my_win->end();
  my_win->show();

  return Fl::run();
}
/*************************************************************************/
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to