> Hi , yes after seeing the example compiled which is great example
> this is what i needed only with one addition that is to be able to
> move the component on the canvas with the handles

OK - here's a revised example that allows moving of the group either by 
middle-drag on the handles, or by dragging the outer group.

Also, I have cleaned up the code a bit and put most of the nasty stuff into the 
derived outer_group class.
Still not a clean implementation, but a bit tidier.
And I set the resize cursors, as per Albrecht's suggestion.

This is probably all I'll do on this, but there should be enough there to let 
you figure out the rest. have fun.

--------
//
// resizeable group test
// fltk-config --compile demo.cxx
//
#include <stdio.h>

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Text_Editor.H>
#include <FL/fl_draw.H>

/* XPM */
static char *grip_tile_xpm[] = {
"6 6 4 1",
"       c None",
".      c #FCFEFC",
"+      c #D4D6D4",
"@      c #9C9294",
".+++++",
"+...@+.++",
"+...@+",
".+++++",
"+...@+.++",
"+...@+"};

// forward declare this class so I can use it to make outer here.
class outer_group;

static Fl_Double_Window *main_win = NULL;
static outer_group *outer = NULL;

// defines for the grab corners - top-left and bottom-right
#define TL -1
#define BR  1

// drag-button grab handles
class drag_btn : public Fl_Box {
private:
  int x1, y1; // click posn., used for dragging checks
  int corner; // which corner...

protected:
  // override box draw method to do our textured dragger look
  void draw();
  // override handle method to catch drag operations
  int handle(int event);

public:
  // basic constructor
  drag_btn(int x, int y, int cr);
};

//constructor
drag_btn::drag_btn(int x, int y, int cr)
 : Fl_Box(x, y, 10, 10) {
  box(FL_THIN_DOWN_BOX);
  corner = cr;
}

//over-ridden draw method
void drag_btn::draw() {
  int xo = x();
  int yo = y();
  // Draw the button box
  draw_box(box(), color());
  // set the clip region so we only "tile" the box
  fl_push_clip(xo+1, yo+1, w()-3, h()-3);
  // tile the pixmap onto the button face... there must be a better way
  for(int i = 2; i <= w(); i += 6)
    for(int j = 2; j <= h(); j += 6)
      fl_draw_pixmap(grip_tile_xpm, (xo + i), (yo + j));
  fl_pop_clip();
} // draw

// over-ridden handle
int drag_btn::handle(int event) {
  int ret = Fl_Box::handle(event);
  int dx, dy, xr, yr;
  int xg, yg, wg, hg;

  xr = Fl::event_x_root();
  yr = Fl::event_y_root();
  switch (event) {
  case FL_PUSH: // downclick in button stores cursor offsets
    x1 = xr;
    y1 = yr;
    ret = 1;
    break;

  case FL_DRAG: // drag the button (and its parent group) around the screen
    dx = xr - x1; dy = yr - y1;
    x1 = xr; y1 = yr;
    if(Fl::event_inside(3, 3, main_win->w()-6, main_win->h()-6)) {
      // now resize/move the enclosing group
      xg = parent()->x();
      yg = parent()->y();
      wg = parent()->w();
      hg = parent()->h();
      // use the middle button to move the window
      if(Fl::event_button2()) {
        parent()->position(xg+dx, yg+dy);
        main_win->redraw();
      }
      else { // treat as a resize
        if(corner == TL) {
          parent()->resize(xg+dx, yg+dy, wg-dx, hg-dy);
          main_win->redraw();
        }
        else if (corner == BR) {
          parent()->resize(xg, yg, wg+dx, hg+dy);
          main_win->redraw();
        }
      }
    }
    ret = 1;
    break;

  case FL_RELEASE:
    ret = 1;
    break;

  case FL_ENTER:
    window()->cursor(FL_CURSOR_MOVE);
    ret = 1;
    break;

  case FL_LEAVE:
    window()->cursor(FL_CURSOR_DEFAULT);
    ret = 1;
    break;

  default:
    break;
  }

  return ret;
} // handle

// enclosing group class
class outer_group : public Fl_Group {
private:
  int x1, y1; // click posn., used for dragging checks
  drag_btn *b1;
  drag_btn *b2;

protected:
  // override handle method to catch drag operations
  int handle(int event);

public:
  // basic constructor
  outer_group(int X, int Y, int W, int H);

  // make the inner group public so I can access it - nasty
  Fl_Group *inner;
};

// constructor
outer_group:: outer_group(int X, int Y, int W, int H)
  : Fl_Group(X,Y,W,H) {
  box(FL_ENGRAVED_BOX);
  color(fl_darker(FL_BACKGROUND_COLOR));
  b1 = new drag_btn(X, Y, TL);
  b2 = new drag_btn(X+W-10, Y+H-10, BR);
  inner = new Fl_Group(X+10, Y+10, W-20, H-20);
  inner->end();
  inner->box(FL_THIN_DOWN_BOX);
  resizable(inner);
} // constructor

// over-ridden handle
int outer_group::handle(int event) {
  int ret = Fl_Group::handle(event);
  if(ret) return ret; // nothing more to do here

  int dx, dy;
  int xg, yg;
  int xr = Fl::event_x_root();
  int yr = Fl::event_y_root();
  switch (event) {
  case FL_PUSH: // downclick in group stores cursor offsets
    x1 = xr;
    y1 = yr;
    ret = 1;
    break;

  case FL_DRAG: // drag the group around the screen
    dx = xr - x1; dy = yr - y1;
    x1 = xr; y1 = yr;
    if(Fl::event_inside(3, 3, main_win->w()-6, main_win->h()-6)) {
      // now move the group
      xg = x();
      yg = y();
      position(xg+dx, yg+dy);
      parent()->redraw();
    }
    ret = 1;
    break;

  case FL_RELEASE:
    ret = 1;
    break;

  default:
    break;
  }

  return ret;
} // handle

// main test harness code
int main(int argc, char **argv) {
  main_win = new Fl_Double_Window(500, 500, "main");
  main_win->begin();
    outer = new outer_group(20, 20, 110, 110);
    outer->end();

    outer->inner->begin();
      Fl_Text_Buffer *buff = new Fl_Text_Buffer();
      Fl_Text_Editor *disp = new Fl_Text_Editor(30, 30, 90, 90);
      disp->buffer(buff);
    outer->inner->end();
    outer->inner->resizable(disp);

  main_win->end();
  main_win->show(argc, argv);

  // fill the editor with some dummy text
  buff->text("line 0\nline 1\nline 2\n"
             "line 3\nline 4\nline 5\n"
             "line 6\nline 7\nline 8\n"
             "line 9\nline 10\nline 11\n"
             "line 12\nline 13\nline 14\n"
             "line 15\nline 16\nline 17\n"
             "line 18\nline 19\nline 20\n"
             "line 21\nline 22\nline 23\n");

  return Fl::run();
} // main
/* End of File */


--------


_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to