Added Fl_Tabs::client_area() (STR #2480).

Fixed some typos in CHANGES.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@8101 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Albrecht Schlosser 2010-12-22 13:06:03 +00:00
parent 1f39dbe5fc
commit ada206d8f7
3 changed files with 146 additions and 55 deletions

25
CHANGES
View File

@ -3,7 +3,7 @@ CHANGES IN FLTK 1.3.0
New Features
- Added UTF-8 Unicode supprt
- Added UTF-8 Unicode support
- Added Fl_Tree widget for hierarchical views
- Added Fl_Table widget for widget layout
- Added Fl_Native_Filechooser as a widget and global options
@ -13,7 +13,9 @@ CHANGES IN FLTK 1.3.0
- Added basic Fl_Device abstraction layer for all drawing functions
Other Additions
- Added new method client_area() for easier positioning of children
in Fl_Tabs (STR #2480)
- Added global UI options (STR #2471)
- Added drag'n'drop support for Fl_Text_*
- Added new label and image alignments (STR #2269)
@ -28,7 +30,7 @@ CHANGES IN FLTK 1.3.0
- Added class Fl_Widget_Tracker to simplify safe handling of widget
deletion in callbacks. This is used in Fl_Widget::do_callback()
to prevent accessing widgets after deletion in the callback.
- Added argument-less constructor in Fuid Widget Class
- Added argument-less constructor in Fluid Widget Class
- Added Fl_Menu_::find_item by callback
- Added indexing to Fl_Preferences
- Added jpeg support to Fluid image() element
@ -42,7 +44,7 @@ CHANGES IN FLTK 1.3.0
- Added "ide" subdirectory for all IDE support files
- Added Fl_Menu_ methods: insert(), find_index(), clear_submenu()
- Added menu shortcut alignment for OS X
- Added drop box to utf8 test that will show the utf8 encoding
- Added drop box to UTF-8 test that will show the UTF-8 encoding
for the first dropped character
- Added flexible gap size for text buffer (STR #2046)
- Added sorting to Fl_Browser_ (STR #2113)
@ -50,7 +52,7 @@ CHANGES IN FLTK 1.3.0
- Added scroll_to(int,int) to Fl_Scroll, replacing
position(int,int) which now behaves as it should (STR #1303)
- Added alternative text input awareness on OS X
Documentation
- Added documentation for event delivery (STR #1983)
@ -59,10 +61,10 @@ CHANGES IN FLTK 1.3.0
- Updated Copyright dates to 2010 (STR #2036)
- Updated mirror sites in documentation (STR #2220)
- Fixed documentation for Fl_Progress (STR #2209)
- Fixed documentation (added missing COMCTRL32.LIB dependency)
- Fixed documentation (added missing COMCTL32.LIB dependency)
Improvements
- Moved OS X code base to the more modern Cocoa toolkit thanks
to the awesome work of Manolo Gouy (STR #2221)
- Improved handling of composed keys in OS X 10.5 and up
@ -210,11 +212,10 @@ CHANGES IN FLTK 1.3.0
- Removed Watcom compiler support because it was introduced in
1.1.6 as a partial solution and never completed.
- Removed an XForms compatibility "feature" that prevented the down
array of Fl_Menu_Button from drawing (STR #2141).
- Removed an XForms compatibility "feature" that prevented the
down array of Fl_Menu_Button from drawing (STR #2141).
- Removed support for gcc 2.x (or older)
- Removed redundant Fl_Group casts
CHANGES IN FLTK 1.1.9
@ -223,7 +224,7 @@ CHANGES IN FLTK 1.1.9
- Fixed regression in callback handling (STR #1918)
- Fixed wrong relative path when absolute path has a
trailing slash in fl_filename_relative (STR #1920)
- Fixed multiple selction of files and directories in
- Fixed multiple selection of files and directories in
Fl_File_Chooser (STR #1913)
- Fixed MSWindows crash when selecting umlauts
in Fl_Help_View (STR #1912)

View File

@ -62,7 +62,11 @@
class FL_EXPORT Fl_Tabs : public Fl_Group {
Fl_Widget *value_;
Fl_Widget *push_;
int tab_positions(int*, int*);
int *tab_pos; // array of x-offsets of tabs per child + 1
int *tab_width; // array of widths of tabs per child + 1
int tab_count; // array size
int tab_positions(); // allocate and calculate tab positions
void clear_tab_positions();
int tab_height();
void draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int sel=0);
protected:
@ -77,6 +81,8 @@ public:
int push(Fl_Widget *);
Fl_Tabs(int,int,int,int,const char * = 0);
Fl_Widget *which(int event_x, int event_y);
~Fl_Tabs();
void client_area(int &rx, int &ry, int &rw, int &rh, int tabh=0);
};
#endif

View File

@ -42,60 +42,74 @@
#define EXTRASPACE 10
#define SELECTION_BORDER 5
// return the left edges of each tab (plus a fake left edge for a tab
// past the right-hand one). These position are actually of the left
// Return the left edges of each tab (plus a fake left edge for a tab
// past the right-hand one). These positions are actually of the left
// edge of the slope. They are either separated by the correct distance
// or by EXTRASPACE or by zero.
// These positions are updated in the private arrays tab_pos[] and
// tab_width[], resp.. If needed, these arrays are (re)allocated.
// Return value is the index of the selected item.
int Fl_Tabs::tab_positions(int* p, int* wp) {
int Fl_Tabs::tab_positions() {
int nc = children();
if (nc != tab_count) {
clear_tab_positions();
if (nc) {
tab_pos = (int*)malloc((nc+1)*sizeof(int));
tab_width = (int*)malloc((nc+1)*sizeof(int));
}
tab_count = nc;
}
if (nc == 0) return 0;
int selected = 0;
Fl_Widget*const* a = array();
int i;
char prev_draw_shortcut = fl_draw_shortcut;
fl_draw_shortcut = 1;
p[0] = Fl::box_dx(box());
for (i=0; i<children(); i++) {
tab_pos[0] = Fl::box_dx(box());
for (i=0; i<nc; i++) {
Fl_Widget* o = *a++;
if (o->visible()) selected = i;
int wt = 0; int ht = 0;
o->measure_label(wt,ht);
wp[i] = wt+EXTRASPACE;
p[i+1] = p[i]+wp[i]+BORDER;
tab_width[i] = wt + EXTRASPACE;
tab_pos[i+1] = tab_pos[i] + tab_width[i] + BORDER;
}
fl_draw_shortcut = prev_draw_shortcut;
int r = w();
if (p[i] <= r) return selected;
if (tab_pos[i] <= r) return selected;
// uh oh, they are too big:
// pack them against right edge:
p[i] = r;
for (i = children(); i--;) {
int l = r-wp[i];
if (p[i+1] < l) l = p[i+1];
if (p[i] <= l) break;
p[i] = l;
tab_pos[i] = r;
for (i = nc; i--;) {
int l = r-tab_width[i];
if (tab_pos[i+1] < l) l = tab_pos[i+1];
if (tab_pos[i] <= l) break;
tab_pos[i] = l;
r -= EXTRASPACE;
}
// pack them against left edge and truncate width if they still don't fit:
for (i = 0; i<children(); i++) {
if (p[i] >= i*EXTRASPACE) break;
p[i] = i*EXTRASPACE;
int W = w()-1-EXTRASPACE*(children()-i) - p[i];
if (wp[i] > W) wp[i] = W;
for (i = 0; i<nc; i++) {
if (tab_pos[i] >= i*EXTRASPACE) break;
tab_pos[i] = i*EXTRASPACE;
int W = w()-1-EXTRASPACE*(children()-i) - tab_pos[i];
if (tab_width[i] > W) tab_width[i] = W;
}
// adjust edges according to visiblity:
for (i = children(); i > selected; i--) {
p[i] = p[i-1]+wp[i-1];
for (i = nc; i > selected; i--) {
tab_pos[i] = tab_pos[i-1] + tab_width[i-1];
}
return selected;
}
// return space needed for tabs. Negative to put them on the bottom:
// Returns space (height) in pixels needed for tabs. Negative to put them on the bottom.
// Returns full height, if children() = 0.
int Fl_Tabs::tab_height() {
if (children() == 0) return h();
int H = h();
int H2 = y();
Fl_Widget*const* a = array();
@ -109,8 +123,10 @@ int Fl_Tabs::tab_height() {
else return (H <= 0) ? 0 : H;
}
// this is used by fluid to pick tabs:
// This is used for event handling (clicks) and by fluid to pick tabs.
// Returns 0, if children() = 0, or if the event is outside of the tabs area.
Fl_Widget *Fl_Tabs::which(int event_x, int event_y) {
if (children() == 0) return 0;
int H = tab_height();
if (H < 0) {
if (event_y > y()+h() || event_y < y()+h()+H) return 0;
@ -120,17 +136,13 @@ Fl_Widget *Fl_Tabs::which(int event_x, int event_y) {
if (event_x < x()) return 0;
Fl_Widget *ret = 0L;
int nc = children();
int *p = (int*)malloc((nc+1)*sizeof(int));
int *wp = (int*)malloc((nc+1)*sizeof(int));
tab_positions(p, wp);
for (int i=0; i<children(); i++) {
if (event_x < x()+p[i+1]) {
tab_positions();
for (int i=0; i<nc; i++) {
if (event_x < x()+tab_pos[i+1]) {
ret = child(i);
break;
}
}
free(p);
free(wp);
return ret;
}
@ -325,21 +337,20 @@ void Fl_Tabs::draw() {
}
if (damage() & (FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) {
int nc = children();
int *p = (int*)malloc((nc+1)*sizeof(int));
int *wp = (int*)malloc((nc+1)*sizeof(int));
int selected = tab_positions(p,wp);
int selected = tab_positions();
int i;
Fl_Widget*const* a = array();
for (i=0; i<selected; i++)
draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], LEFT);
for (i=children()-1; i > selected; i--)
draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], RIGHT);
draw_tab(x()+tab_pos[i], x()+tab_pos[i+1],
tab_width[i], H, a[i], LEFT);
for (i=nc-1; i > selected; i--)
draw_tab(x()+tab_pos[i], x()+tab_pos[i+1],
tab_width[i], H, a[i], RIGHT);
if (v) {
i = selected;
draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], SELECTED);
draw_tab(x()+tab_pos[i], x()+tab_pos[i+1],
tab_width[i], H, a[i], SELECTED);
}
free(p);
free(wp);
}
}
@ -420,11 +431,11 @@ void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) {
away from the top or bottom edge of the Fl_Tabs widget,
which is where the tabs will be drawn.
All children of Fl_Tab should have the same size and exactly fit on top of
All children of Fl_Tabs should have the same size and exactly fit on top of
each other. They should only leave space above or below where that tabs will
go, but not on the sides. If the first child of Fl_Tab is set to
go, but not on the sides. If the first child of Fl_Tabs is set to
"resizable()", the riders will not resize when the tabs are resized.
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
@ -437,6 +448,79 @@ Fl_Tabs::Fl_Tabs(int X,int Y,int W, int H, const char *l) :
{
box(FL_THIN_UP_BOX);
push_ = 0;
tab_pos = 0;
tab_width = 0;
tab_count = 0;
}
Fl_Tabs::~Fl_Tabs() {
clear_tab_positions();
}
/**
Returns the position and size available to be used by its children.
If there isn't any child yet the \p tabh parameter will be used to
calculate the return values. This assumes that the children's labelsize
is the same as the Fl_Tabs' labelsize and adds a small border.
If there are already children, the values of child(0) are returned, and
\p tabh is ignored.
\note Children should always use the same positions and sizes.
\p tabh can be one of
\li 0: calculate label size, tabs on top
\li -1: calculate label size, tabs on bottom
\li > 0: use given \p tabh value, tabs on top (height = tabh)
\li < -1: use given \p tabh value, tabs on bottom (height = -tabh)
\param[in] tabh position and optional height of tabs (see above)
\param[out] rx,ry,rw,rh (x,y,w,h) of client area for children
*/
void Fl_Tabs::client_area(int &rx, int &ry, int &rw, int &rh, int tabh) {
if (children()) { // use existing values
rx = child(0)->x();
ry = child(0)->y();
rw = child(0)->w();
rh = child(0)->h();
} else { // calculate values
int y_offset;
int label_height = fl_height(labelfont(), labelsize()) + BORDER*2;
if (tabh == 0) // use default (at top)
y_offset = label_height;
else if (tabh == -1) // use default (at bottom)
y_offset = -label_height;
else
y_offset = tabh; // user given value
rx = x();
rw = w();
if (y_offset >= 0) { // labels at top
ry = y() + y_offset;
rh = h() - y_offset;
} else { // labels at bottom
ry = y();
rh = h() + y_offset;
}
}
}
void Fl_Tabs::clear_tab_positions() {
if (tab_pos) {
free(tab_pos);
tab_pos = 0;
}
if (tab_width){
free(tab_width);
tab_width = 0;
}
}
//