DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2791
Version: 1.3-feature


Attached file "tiletest.cxx"...


Link: http://www.fltk.org/str.php?L2791
Version: 1.3-feature
//
// "$Id: tiletest.cxx 2011-12-10 23:18:18Z r_strickland $"
//
//  Adapted from: 
// "$Id: tile.cxx 7903 2010-11-28 21:06:39Z matt $"
//
// Tile test program for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems on the following page:
//
//     http://www.fltk.org/str.php
//

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Tile.H>
#include <FL/Fl_Box.H>

//#define TEST_INACTIVE

/**
  Fl_TileM inherits from Fl_Tile. It functions similarly, but it
  enforces a minimum tile size

  TODO: the minimum sizes do not cascade. If you drag a separator
  into a tile that is already minimal in size, dragging ceases. It
  might be better if it were to push the minimal tile along until
  it reaches the edge.
*/
class Fl_TileM:public Fl_Tile {
protected:
  Fl_Cursor cursors[4];
  Fl_Cursor cursor;
  int thresh; // minimum window width or height in pixels
public:
  Fl_TileM(int x, int y, int w, int h, const char*l=0, int t=0)
      : Fl_Tile(x, y, w, h, l) {
    thresh = t;
    cursors[0] = FL_CURSOR_DEFAULT;
    cursors[1] = FL_CURSOR_WE;
    cursors[2] = FL_CURSOR_NS;
    cursors[3] = FL_CURSOR_MOVE;
  };
  void position(int oix, int oiy, int newx, int newy); // override
  int handle(int event); // override. See note below.
  void set_thresh(int t) { thresh = t; };
protected:
  void set_cursor(Fl_Cursor c) {
    if (cursor == c || !window()) return;
    cursor = c;
#ifdef __sgi
    window()->cursor(c,FL_RED,FL_WHITE);
#else
    window()->cursor(c);
#endif
  };
};

/**
  Drag the edges that were initially (that is, when constructed) at
  oix,oiy to newx,newy.

  Pass zero as oix or oiy to disable drag in that direction.
  This redraws all the necessary children.
*/
void Fl_TileM::position(int oix, int oiy, int newx, int newy) {
  int nchild = children();
  //
  // pass == 0: calculate new sizes but return if resizing would 
  //            make an undersized child
  // pass == 1: do the resizing
  //
  for (int pass = 0; pass < 2; pass++) {
    Fl_Widget*const* a = array();
    int *p = sizes();
    p += 8; // skip group & resizable's saved size
    for (int i = 0; i < nchild; i++, p += 4) {
      Fl_Widget* o = *a++;
      if (o == resizable()) continue;
      int L = o->x();
      int R = L+o->w();
      bool damage = false;
      if (oix) {
        int t = p[0];
        if (t==oix || (t>oix && L<newx) || (t<oix && L>newx)) {
          L = newx;
          damage = true;
        }
        t = p[1];
        if (t==oix || (t>oix && R<newx) || (t<oix && R>newx)) {
          R = newx;
          damage = true;
        }
        if (damage && !pass && R-L < thresh) return;
      }
      int T = o->y();
      int B = T+o->h();
      if (oiy) {
        int t = p[2];
        if (t==oiy || (t>oiy && T<newy) || (t<oiy && T>newy)) {
          T = newy;
          damage = true;
        }
        t = p[3];
        if (t==oiy || (t>oiy && B<newy) || (t<oiy && B>newy)) {
          B = newy;
          damage = true;
        }
        if (damage && !pass && B-T < thresh) return;
      }
      if (pass && damage) o->damage_resize(L,T,R-L,B-T);
    }
  }
}

//
// Note: The changes to Fl_Tile::handle() have nothing to do
// with the minimum size threshold. They are to encapsulate the
// formerly static set_cursor() and associated cursor data.
// These prevented Fl_Tile::handle from being overridden.
//
int Fl_TileM::handle(int event) {
  static int sdrag;
  static int sdx, sdy;
  static int sx, sy;
#define DRAGH 1
#define DRAGV 2
#define GRABAREA 4

  int mx = Fl::event_x();
  int my = Fl::event_y();

  switch (event) {

  case FL_MOVE:
  case FL_ENTER:
  case FL_PUSH:
    // don't potentially change the mouse cursor if inactive:
    if (!active()) break; // will cascade inherited handle()
    {
    int mindx = 100;
    int mindy = 100;
    int oix = 0;
    int oiy = 0;
    Fl_Widget*const* a = array();
    int *q = sizes();
    int *p = q+8;
    for (int i=children(); i--; p += 4) {
      Fl_Widget* o = *a++;
      if (o == resizable()) continue;
      if (p[1]<q[1] && o->y()<=my+GRABAREA && o->y()+o->h()>=my-GRABAREA) {
        int t = mx - (o->x()+o->w());
        if (abs(t) < mindx) {
          sdx = t;
          mindx = abs(t);
          oix = p[1];
        }
      }
      if (p[3]<q[3] && o->x()<=mx+GRABAREA && o->x()+o->w()>=mx-GRABAREA) {
        int t = my - (o->y()+o->h());
        if (abs(t) < mindy) {
          sdy = t;
          mindy = abs(t);
          oiy = p[3];
        }
      }
    }
    sdrag = 0; sx = sy = 0;
    if (mindx <= GRABAREA) {sdrag = DRAGH; sx = oix;}
    if (mindy <= GRABAREA) {sdrag |= DRAGV; sy = oiy;}
    set_cursor(cursors[sdrag]);
    if (sdrag) return 1;
    return Fl_Group::handle(event);
  }

  case FL_LEAVE:
    set_cursor(FL_CURSOR_DEFAULT);
    break;

  case FL_DRAG:
    // This is necessary if CONSOLIDATE_MOTION in Fl_x.cxx is turned off:
    // if (damage()) return 1; // don't fall behind
  case FL_RELEASE: {
    if (!sdrag) return 0; // should not happen
    Fl_Widget* r = resizable(); if (!r) r = this;
    int newx;
    if (sdrag&DRAGH) {
      newx = Fl::event_x()-sdx;
      if (newx < r->x()) newx = r->x();
      else if (newx > r->x()+r->w()) newx = r->x()+r->w();
    } else
      newx = sx;
    int newy;
    if (sdrag&DRAGV) {
      newy = Fl::event_y()-sdy;
      if (newy < r->y()) newy = r->y();
      else if (newy > r->y()+r->h()) newy = r->y()+r->h();
    } else
      newy = sy;
    position(sx,sy,newx,newy);
    if (event == FL_DRAG) set_changed();
    do_callback();
    return 1;}
  }
  return Fl_Group::handle(event);
}

#define BOXTYPE FL_DOWN_BOX

int main(int argc, char** argv) {
  Fl_Double_Window window(300,300, "Fl_TileM Test");
  window.box(FL_NO_BOX);
  window.resizable(window);
  Fl_TileM tile(0, 0, 300, 300, 0, 3); // threshold = 3 good for
                                       // FL_DOWN_BOX

  Fl_Box box0(0,0,150,150,"0");
  box0.box(BOXTYPE);
  box0.color(9);
  box0.labelsize(36);
  box0.align(FL_ALIGN_CLIP);

  Fl_Double_Window w1(150,0,150,150,"1");
  Fl_Box box1(0,0,150,150,"1\nThis is a\nchild\nwindow");
  w1.box(FL_NO_BOX);
  box1.box(BOXTYPE);
  w1.resizable(box1);
  w1.end();

  Fl_Box box2a(0,150,70,150,"2a");
  box2a.box(BOXTYPE);
  box2a.color(12);
  box2a.labelsize(36);
  box2a.align(FL_ALIGN_CLIP);
  Fl_Box box2b(70,150,80,150,"2b");
  box2b.box(BOXTYPE);
  box2b.color(13);
  box2b.labelsize(36);
  box2b.align(FL_ALIGN_CLIP);

  Fl_Box box3a(150,150,150,70,"3a");
  box3a.box(BOXTYPE);
  box3a.color(12);
  box3a.labelsize(36);
  box3a.align(FL_ALIGN_CLIP);
  Fl_Box box3b(150,150+70,150,80,"3b");
  box3b.box(BOXTYPE);
  box3b.color(13);
  box3b.labelsize(36);
  box3b.align(FL_ALIGN_CLIP);
  
/*
  Fl_Box r(10,0,300-10,300-10);
  tile.resizable(r);
  // r.box(FL_BORDER_FRAME);
*/

  tile.end();
  window.end();
#ifdef TEST_INACTIVE // test inactive case 
  tile.deactivate();
#endif
  w1.show();
  window.show(argc,argv);
  return Fl::run();
}

//
// End of "$Id: tiletest.cxx 2011-12-10 23:18:18Z r_strickland $"
//
_______________________________________________
fltk-bugs mailing list
fltk-bugs@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-bugs

Reply via email to