mirror of https://github.com/fltk/fltk
Improve and reorganize Fl_Tile's documentation and test/tile demo.
Moved docs from header file and enhanced docs, particularly about the resizable() widget and the resize behavior in general. Changed the tile demo program to use a resizable() with 20 pixels border distance, so that border dragging is limited as described in the docs. Updated the image file to reflect the current test/tile.cxx demo. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10385 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
157c5bf15e
commit
25cf93b4cb
64
FL/Fl_Tile.H
64
FL/Fl_Tile.H
|
@ -3,10 +3,10 @@
|
|||
//
|
||||
// Tile header file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
|
@ -16,71 +16,19 @@
|
|||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
/* \file
|
||||
Fl_Tile widget . */
|
||||
|
||||
#ifndef Fl_Tile_H
|
||||
#define Fl_Tile_H
|
||||
|
||||
#include "Fl_Group.H"
|
||||
|
||||
/**
|
||||
The Fl_Tile class lets you resize the children by dragging
|
||||
the border between them:
|
||||
|
||||
<P ALIGN=CENTER>\image html Fl_Tile.png </P>
|
||||
\image latex Fl_Tile.png "Fl_Tile" width=4cm
|
||||
|
||||
<P>For the tiling to work correctly, the children of an
|
||||
Fl_Tile must cover the entire area of the widget, but not
|
||||
overlap. This means that all children must touch each
|
||||
other at their edges, and no gaps can't be left inside the
|
||||
Fl_Tile.
|
||||
|
||||
<P>Fl_Tile does not normailly draw any graphics of its own.
|
||||
The "borders" which can be seen in the snapshot above
|
||||
are actually part of the children. Their boxtypes have been set
|
||||
to FL_DOWN_BOX creating the impression of
|
||||
"ridges" where the boxes touch. What you see are
|
||||
actually two adjacent FL_DOWN_BOX's drawn next to each
|
||||
other. All neighboring widgets share the same edge - the widget's
|
||||
thick borders make it appear as though the widgets aren't actually
|
||||
touching, but they are. If the edges of adjacent widgets do not
|
||||
touch, then it will be impossible to drag the corresponding
|
||||
edges.</P>
|
||||
|
||||
<P>Fl_Tile allows objects to be resized to zero dimensions.
|
||||
To prevent this you can use the resizable() to limit where
|
||||
corners can be dragged to.</P>
|
||||
|
||||
<P>Even though objects can be resized to zero sizes, they must
|
||||
initially have non-zero sizes so the Fl_Tile can figure out
|
||||
their layout. If desired, call position() after creating the
|
||||
children but before displaying the window to set the borders where you
|
||||
want.
|
||||
|
||||
<P>Note on resizable(Fl_Widget &w) :
|
||||
The "resizable" child widget (which should be invisible) limits where the
|
||||
border can be dragged to. If you don't set it, it will be possible to
|
||||
drag the borders right to the edge, and thus resize objects on the edge
|
||||
to zero width or height. The resizable() widget is not
|
||||
resized by dragging any borders. See also void Fl_Group::resizable(Fl_Widget &w)
|
||||
|
||||
/*
|
||||
The Fl_Tile class lets you resize its children by dragging
|
||||
the border between them.
|
||||
*/
|
||||
|
||||
class FL_EXPORT Fl_Tile : public Fl_Group {
|
||||
public:
|
||||
int handle(int);
|
||||
/**
|
||||
Creates a new Fl_Tile widget using the given position, size,
|
||||
and label string. The default boxtype is FL_NO_BOX.
|
||||
|
||||
<P>The destructor <I>also deletes all the children</I>. This allows a
|
||||
whole tree to be deleted at once, without having to keep a pointer to
|
||||
all the children in the user code. A kludge has been done so the
|
||||
Fl_Tile and all of it's children can be automatic (local)
|
||||
variables, but you must declare the Fl_Tile <I>first</I>, so
|
||||
that it is destroyed last.
|
||||
*/
|
||||
Fl_Tile(int X,int Y,int W,int H,const char*l=0);
|
||||
void resize(int, int, int, int);
|
||||
void position(int, int, int, int);
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 8.3 KiB |
142
src/Fl_Tile.cxx
142
src/Fl_Tile.cxx
|
@ -3,10 +3,10 @@
|
|||
//
|
||||
// Tile widget for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
|
@ -16,23 +16,81 @@
|
|||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
/**
|
||||
\class Fl_Tile
|
||||
|
||||
// Group of 2 or 4 "tiles" that can be resized by dragging border
|
||||
// The size of the first child determines where the resize border is.
|
||||
// The resizebox is used to limit where the border can be dragged to.
|
||||
The Fl_Tile class lets you resize its children by dragging
|
||||
the border between them.
|
||||
|
||||
\image html Fl_Tile.png
|
||||
\image latex Fl_Tile.png "Fl_Tile" width=5cm
|
||||
|
||||
For the tiling to work correctly, the children of an Fl_Tile must
|
||||
cover the entire area of the widget, but not overlap.
|
||||
This means that all children must touch each other at their edges,
|
||||
and no gaps can be left inside the Fl_Tile.
|
||||
|
||||
Fl_Tile does not normally draw any graphics of its own.
|
||||
The "borders" which can be seen in the snapshot above are actually
|
||||
part of the children. Their boxtypes have been set to FL_DOWN_BOX
|
||||
creating the impression of "ridges" where the boxes touch. What
|
||||
you see are actually two adjacent FL_DOWN_BOX's drawn next to each
|
||||
other. All neighboring widgets share the same edge - the widget's
|
||||
thick borders make it appear as though the widgets aren't actually
|
||||
touching, but they are. If the edges of adjacent widgets do not
|
||||
touch, then it will be impossible to drag the corresponding edges.
|
||||
|
||||
Fl_Tile allows objects to be resized to zero dimensions.
|
||||
To prevent this you can use the resizable() to limit where
|
||||
corners can be dragged to. For more information see note below.
|
||||
|
||||
Even though objects can be resized to zero sizes, they must initially
|
||||
have non-zero sizes so the Fl_Tile can figure out their layout.
|
||||
If desired, call position() after creating the children but before
|
||||
displaying the window to set the borders where you want.
|
||||
|
||||
<b>Note on resizable(Fl_Widget &w):</b>
|
||||
The "resizable" child widget (which should be invisible) limits where
|
||||
the borders can be dragged to. All dragging will be limited inside the
|
||||
resizable widget's borders. If you don't set it, it will be possible
|
||||
to drag the borders right to the edges of the Fl_Tile widget, and thus
|
||||
resize objects on the edges to zero width or height. When the entire
|
||||
Fl_Tile widget is resized, the resizable() widget will keep its border
|
||||
distance to all borders the same (this is normal resize behavior), so
|
||||
that you can effectively set a border width that will never change.
|
||||
|
||||
<b>Note:</b>
|
||||
You can still resize widgets \b inside the resizable() to zero width and/or
|
||||
height, i.e. box \b 2b above to zero width and box \b 3a to zero height.
|
||||
|
||||
\see void Fl_Group::resizable(Fl_Widget &w)
|
||||
|
||||
Example for resizable with 20 pixel border distance:
|
||||
\code
|
||||
int dx = 20, dy = dx;
|
||||
Fl_Tile tile(50,50,300,300);
|
||||
// ... create widgets inside tile (see test/tile.cxx) ...
|
||||
// create resizable() box
|
||||
Fl_Box r(tile.x()+dx,tile.y()+dy,tile.w()-2*dx,tile.h()-2*dy);
|
||||
tile.resizable(r);
|
||||
tile.end();
|
||||
\endcode
|
||||
|
||||
See also the complete example program in test/tile.cxx.
|
||||
*/
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Tile.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Drag the edges that were initially at oldx,oldy to newx,newy:
|
||||
// pass zero as oldx or oldy to disable drag in that direction:
|
||||
/**
|
||||
Drag the intersection at from_x,from_y to to_x,to_y.
|
||||
/**
|
||||
Drags the intersection at (\p oldx,\p oldy) to (\p newx,\p newy).
|
||||
This redraws all the necessary children.
|
||||
|
||||
Pass zero as \p oldx or \p oldy to disable drag in that direction.
|
||||
*/
|
||||
void Fl_Tile::position(int oix, int oiy, int newx, int newy) {
|
||||
void Fl_Tile::position(int oldx, int oldy, int newx, int newy) {
|
||||
Fl_Widget*const* a = array();
|
||||
int *p = sizes();
|
||||
p += 8; // skip group & resizable's saved size
|
||||
|
@ -41,28 +99,43 @@ void Fl_Tile::position(int oix, int oiy, int newx, int newy) {
|
|||
if (o == resizable()) continue;
|
||||
int X = o->x();
|
||||
int R = X+o->w();
|
||||
if (oix) {
|
||||
if (oldx) {
|
||||
int t = p[0];
|
||||
if (t == oix || (t>oix && X<newx) || (t<oix && X>newx) ) X = newx;
|
||||
if (t == oldx || (t>oldx && X<newx) || (t<oldx && X>newx) ) X = newx;
|
||||
t = p[1];
|
||||
if (t == oix || (t>oix && R<newx) || (t<oix && R>newx) ) R = newx;
|
||||
if (t == oldx || (t>oldx && R<newx) || (t<oldx && R>newx) ) R = newx;
|
||||
}
|
||||
int Y = o->y();
|
||||
int B = Y+o->h();
|
||||
if (oiy) {
|
||||
if (oldy) {
|
||||
int t = p[2];
|
||||
if (t == oiy || (t>oiy && Y<newy) || (t<oiy && Y>newy) ) Y = newy;
|
||||
if (t == oldy || (t>oldy && Y<newy) || (t<oldy && Y>newy) ) Y = newy;
|
||||
t = p[3];
|
||||
if (t == oiy || (t>oiy && B<newy) || (t<oiy && B>newy) ) B = newy;
|
||||
if (t == oldy || (t>oldy && B<newy) || (t<oldy && B>newy) ) B = newy;
|
||||
}
|
||||
o->damage_resize(X,Y,R-X,B-Y);
|
||||
}
|
||||
}
|
||||
|
||||
// move the lower-right corner (sort of):
|
||||
/**
|
||||
Resizes the Fl_Tile widget and its children.
|
||||
|
||||
Fl_Tile implements its own resize() method. It does not use
|
||||
Fl_Group::resize() to resize itself and its children.
|
||||
|
||||
Enlarging works by just moving the lower-right corner and resizing
|
||||
the bottom and right border widgets accordingly.
|
||||
|
||||
Shrinking the Fl_Tile works in the opposite way by shrinking
|
||||
the bottom and right border widgets, unless they are reduced to zero
|
||||
width or height, resp. or to their minimal sizes defined by the
|
||||
resizable() widget. In this case other widgets will be shrunk as well.
|
||||
|
||||
See the Fl_Tile class documentation about how the resizable() works.
|
||||
*/
|
||||
|
||||
void Fl_Tile::resize(int X,int Y,int W,int H) {
|
||||
//Fl_Group::resize(X, Y, W, H);
|
||||
//return;
|
||||
|
||||
// remember how much to move the child widgets:
|
||||
int dx = X-x();
|
||||
int dy = Y-y();
|
||||
|
@ -71,11 +144,13 @@ void Fl_Tile::resize(int X,int Y,int W,int H) {
|
|||
int *p = sizes();
|
||||
// resize this (skip the Fl_Group resize):
|
||||
Fl_Widget::resize(X,Y,W,H);
|
||||
// find bottom-right of resiable:
|
||||
int OR = p[5];
|
||||
int NR = X+W-(p[1]-OR);
|
||||
int OB = p[7];
|
||||
int NB = Y+H-(p[3]-OB);
|
||||
|
||||
// find bottom-right corner of resizable:
|
||||
int OR = p[5]; // old right border
|
||||
int NR = X+W-(p[1]-OR); // new right border
|
||||
int OB = p[7]; // old bottom border
|
||||
int NB = Y+H-(p[3]-OB); // new bottom border
|
||||
|
||||
// move everything to be on correct side of new resizable:
|
||||
Fl_Widget*const* a = array();
|
||||
p += 8;
|
||||
|
@ -90,7 +165,7 @@ void Fl_Tile::resize(int X,int Y,int W,int H) {
|
|||
if (*p++ >= OB) yy += dh; else if (yy > NB) yy = NB;
|
||||
if (*p++ >= OB) B += dh; else if (B > NB) B = NB;
|
||||
o->resize(xx,yy,R-xx,B-yy);
|
||||
// do *not* call o->redraw() here! If you do, and the tile is inside a
|
||||
// do *not* call o->redraw() here! If you do, and the tile is inside a
|
||||
// scroll, it'll set the damage areas wrong for all children!
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +275,22 @@ int Fl_Tile::handle(int event) {
|
|||
return Fl_Group::handle(event);
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a new Fl_Tile widget using the given position, size,
|
||||
and label string. The default boxtype is FL_NO_BOX.
|
||||
|
||||
Fl_Tile::Fl_Tile(int X,int Y,int W,int H,const char*l)
|
||||
: Fl_Group(X,Y,W,H,l)
|
||||
The destructor <I>also deletes all the children</I>. This allows a
|
||||
whole tree to be deleted at once, without having to keep a pointer to
|
||||
all the children in the user code. A kludge has been done so the
|
||||
Fl_Tile and all of its children can be automatic (local)
|
||||
variables, but you must declare the Fl_Tile <I>first</I>, so
|
||||
that it is destroyed last.
|
||||
|
||||
\see class Fl_Group
|
||||
*/
|
||||
|
||||
Fl_Tile::Fl_Tile(int X,int Y,int W,int H,const char*l)
|
||||
: Fl_Group(X,Y,W,H,l)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// Tile test program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
|
@ -27,19 +27,23 @@ int main(int argc, char** argv) {
|
|||
Fl_Double_Window window(300,300);
|
||||
window.box(FL_NO_BOX);
|
||||
window.resizable(window);
|
||||
|
||||
int dx = 20, dy = dx; // border width of resizable() - see below
|
||||
Fl_Tile tile(0,0,300,300);
|
||||
|
||||
Fl_Box box0(0,0,150,150,"0");
|
||||
box0.box(FL_DOWN_BOX);
|
||||
box0.color(9);
|
||||
box0.labelsize(36);
|
||||
box0.align(FL_ALIGN_CLIP);
|
||||
|
||||
Fl_Double_Window w1(150,0,150,150,"1");
|
||||
w1.box(FL_NO_BOX);
|
||||
Fl_Box box1(0,0,150,150,"1\nThis is a\nchild\nwindow");
|
||||
Fl_Box box1(0,0,150,150,"1\nThis is a child window");
|
||||
box1.box(FL_DOWN_BOX);
|
||||
box1.color(19);
|
||||
box1.labelsize(18);
|
||||
box1.align(FL_ALIGN_CLIP);
|
||||
box1.align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
|
||||
w1.resizable(box1);
|
||||
w1.end();
|
||||
|
||||
|
@ -49,6 +53,7 @@ int main(int argc, char** argv) {
|
|||
box2a.color(12);
|
||||
box2a.labelsize(36);
|
||||
box2a.align(FL_ALIGN_CLIP);
|
||||
|
||||
Fl_Box box2b(70,150,80,150,"2b");
|
||||
box2b.box(FL_DOWN_BOX);
|
||||
box2b.color(13);
|
||||
|
@ -62,22 +67,27 @@ int main(int argc, char** argv) {
|
|||
box3a.color(12);
|
||||
box3a.labelsize(36);
|
||||
box3a.align(FL_ALIGN_CLIP);
|
||||
|
||||
Fl_Box box3b(150,150+70,150,80,"3b");
|
||||
box3b.box(FL_DOWN_BOX);
|
||||
box3b.color(13);
|
||||
box3b.labelsize(36);
|
||||
box3b.align(FL_ALIGN_CLIP);
|
||||
//tile3.end();
|
||||
|
||||
Fl_Box r(10,0,300-10,300-10);
|
||||
|
||||
// create the symmetrical resize box with dx and dy pixels distance, resp.
|
||||
// from the borders of the Fl_Tile widget
|
||||
Fl_Box r(tile.x()+dx,tile.y()+dy,tile.w()-2*dx,tile.h()-2*dy);
|
||||
tile.resizable(r);
|
||||
// r.box(FL_BORDER_FRAME);
|
||||
|
||||
tile.end();
|
||||
window.end();
|
||||
#ifdef TEST_INACTIVE // test inactive case
|
||||
|
||||
#ifdef TEST_INACTIVE // test inactive case
|
||||
tile.deactivate();
|
||||
#endif
|
||||
|
||||
w1.show();
|
||||
window.show(argc,argv);
|
||||
return Fl::run();
|
||||
|
|
Loading…
Reference in New Issue