#include <FL/Fl.H>
#include <FL/Fl_Tabs.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Tooltip.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Window.H>
#include <stdio.h>
#include <stdlib.h>
#define BORDER 2
#define OV_BORDER 2
#define EXTRASPACE 10
#define SELECTION_BORDER 5
#define EXTRAGAP 2
#define MARGIN 20
enum {LEFT, RIGHT, SELECTED};
static int fl_min(int a, int b) { return a < b ? a : b; }
int Fl_Tabs::on_insert(Fl_Widget* candidate, int index) {
redraw_tabs();
return Fl_Group::on_insert(candidate, index);
}
int Fl_Tabs::on_move(int a, int b) {
redraw_tabs();
return Fl_Group::on_move(a, b);
}
void Fl_Tabs::on_remove(int index) {
redraw_tabs();
if (child(index)->visible()) {
if (index+1<children())
value(child(index+1));
else if (index>0)
value(child(index-1));
}
if (children()==1)
damage(FL_DAMAGE_ALL);
Fl_Group::on_remove(index);
}
void Fl_Tabs::resize(int X, int Y, int W, int H) {
redraw_tabs();
Fl_Group::resize(X, Y, W, H);
}
void Fl_Tabs::show() {
Fl::damage(FL_DAMAGE_SCROLL);
Fl_Group::show();
}
int Fl_Tabs::tab_positions() {
const 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)*sizeof(int));
tab_flags = (int*)malloc((nc)*sizeof(int));
}
tab_count = nc;
}
if (nc == 0) return -1;
int selected = 0;
Fl_Widget*const* a = array();
int i;
char prev_draw_shortcut = fl_draw_shortcut;
fl_draw_shortcut = 1;
int l = 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;
Fl_Labeltype ot = o->labeltype();
Fl_Align oa = o->align();
if (ot == FL_NO_LABEL) {
o->labeltype(FL_NORMAL_LABEL);
}
o->align(tab_align());
o->measure_label(wt,ht);
o->labeltype(ot);
o->align(oa);
if (o->when() & FL_WHEN_CLOSED)
wt += labelsize()/2 + EXTRAGAP;
tab_width[i] = wt + EXTRASPACE;
tab_pos[i+1] = tab_pos[i] + tab_width[i] + BORDER;
tab_flags[i] = 0;
}
fl_draw_shortcut = prev_draw_shortcut;
if (overflow_type == OVERFLOW_COMPRESS) {
int r = w() - Fl::box_dw(box());;
if ( (nc > 1) && (tab_pos[nc] > r) ) {
int wdt = r - l;
int available = wdt - tab_width[selected];
if (available <= 8*nc) {
for (i = 0; i < nc; i++) {
if (i < selected) {
tab_pos[i] = l + 8*i;
tab_flags[i] |= 1;
} else if (i>selected) {
tab_pos[i] = r - (nc-i)*8;
tab_flags[i] |= 1;
} else {
tab_pos[i] = l + 8*i;;
tab_flags[i] &= ~1;
}
tab_pos[nc] = r;
}
} else {
int overflow = tab_pos[nc] - r;
int left_total = tab_pos[selected] - l;
int right_total = tab_pos[nc] - tab_pos[selected+1];
int left_overflow = left_total+right_total ? overflow * left_total / (left_total+right_total) : overflow;
int right_overflow = overflow - left_overflow;
int xdelta = 0; for (i=0; i<selected; i++) { int tw = tab_width[i]; if (left_overflow > 0) { tw -= left_overflow; if (tw < 8) tw = 8; int wdelta = tab_width[i] - tw; left_overflow -= wdelta; xdelta += wdelta; if (wdelta > 16) tab_flags[i] |= 1; }
tab_pos[i+1] -= xdelta; }
xdelta = 0;
for (i=nc-1; i>selected; i--) {
int tw = tab_width[i];
if (right_overflow > 0) {
tw -= right_overflow;
if (tw < 8) tw = 8;
int wdelta = tab_width[i] - tw;
right_overflow -= wdelta;
xdelta += wdelta;
if (wdelta > 4) tab_flags[i] |= 1;
}
tab_pos[i] -= overflow - xdelta;
}
tab_pos[nc] = r;
}
}
}
return selected;
}
int Fl_Tabs::tab_height() {
if (children() == 0) return h();
int H = h();
int H2 = y();
Fl_Widget*const* a = array();
for (int i=children(); i--;) {
Fl_Widget* o = *a++;
if (o->y() < y()+H) H = o->y()-y();
if (o->y()+o->h() > H2) H2 = o->y()+o->h();
}
H2 = y()+h()-H2;
if (H2 > H) return (H2 <= 0) ? 0 : -H2;
else return (H <= 0) ? 0 : H;
}
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;
} else {
if (event_y > y()+H || event_y < y()) return 0;
}
if (event_x < x()) return 0;
Fl_Widget *ret = 0L;
const int nc = children();
tab_positions();
for (int i=0; i<nc; i++) {
if (event_x < x()+tab_pos[i+1]+tab_offset) {
ret = child(i);
break;
}
}
return ret;
}
int Fl_Tabs::hit_close(Fl_Widget *o, int event_x, int event_y) {
(void)event_y;
for (int i=0; i<children(); i++) {
if (child(i)==o) {
if (tab_flags[i] & 1)
return 0;
int tab_x = tab_pos[i] + tab_offset + x();
return ( (event_x >= tab_x)
&& (event_x < tab_x + (labelsize()+EXTRASPACE+EXTRAGAP)/2) );
}
}
return 0;
}
int Fl_Tabs::hit_overflow_menu(int event_x, int event_y) {
if (!has_overflow_menu)
return 0;
int H = tab_height();
if (event_x < x()+w()-abs(H)+OV_BORDER)
return 0;
if (H >= 0) {
if (event_y > y()+H)
return 0;
} else {
if (event_y < y()+h()+H)
return 0;
}
return 1;
}
int Fl_Tabs::hit_tabs_area(int event_x, int event_y) {
int H = tab_height();
if (H >= 0) {
if (event_y > y()+H)
return 0;
} else {
if (event_y < y()+h()+H)
return 0;
}
if (has_overflow_menu && event_x > x()+w()-abs(H)+OV_BORDER)
return 0;
return 1;
}
void Fl_Tabs::check_overflow_menu() {
int nc = children();
int H = tab_height(); if (H < 0) H = -H;
if (tab_pos[nc] > w()-H+OV_BORDER) {
has_overflow_menu = 1;
} else {
has_overflow_menu = 0;
}
}
void Fl_Tabs::take_focus(Fl_Widget *o) {
if (o && Fl::visible_focus() && Fl::focus()!=this) {
Fl::focus(this);
redraw_tabs();
}
}
int Fl_Tabs::maybe_do_callback(Fl_Widget *o) {
if ( o == NULL )
return 0;
int tab_changed = value(o);
if ( tab_changed )
set_changed();
if ( tab_changed || ( when() & (FL_WHEN_NOT_CHANGED) ) ) {
Fl_Widget_Tracker wp(o); do_callback(FL_REASON_SELECTED); if (wp.deleted()) return 0; }
Fl_Tooltip::current(o);
return 1;
}
void Fl_Tabs::handle_overflow_menu() {
int nc = children();
int H = tab_height(); if (H < 0) H = -H;
int i, fv=-1, lv=nc; if (nc <= 0) return;
for (i = 0; i < nc; i++) {
if (tab_pos[i]+tab_offset < 0) fv = i;
if (tab_pos[i]+tab_width[i]+tab_offset <= w()-H+OV_BORDER) lv = i;
}
Fl_Menu_Item* overflow_menu = new Fl_Menu_Item[nc+1];
memset(overflow_menu, 0, sizeof(Fl_Menu_Item)*(nc+1));
for (i = 0; i < nc; i++) {
overflow_menu[i].label(child(i)->label());
overflow_menu[i].user_data(child(i));
overflow_menu[i].labelfont(labelfont());
overflow_menu[i].labelsize(labelsize());
if ( (i == fv) || (i == lv) )
overflow_menu[i].flags |= FL_MENU_DIVIDER;
if (child(i)->visible())
overflow_menu[i].labelfont_ |= FL_BOLD;
}
const Fl_Menu_Item *m = overflow_menu->popup(x()+w()-H+OV_BORDER, (tab_height()>0)?(y()+H):(y()+h()-OV_BORDER));
if (m) {
Fl_Widget *o = (Fl_Widget*)m->user_data();
push(0);
take_focus(o);
maybe_do_callback(o);
}
if (overflow_menu) {
delete[] overflow_menu;
overflow_menu = NULL;
}
}
void Fl_Tabs::draw_overflow_menu_button() {
int H = tab_height();
int X, Y;
if (H > 0) {
X = x() + w() - H + OV_BORDER;
if (OV_BORDER > 0)
fl_rectf(X, y(), H - OV_BORDER, OV_BORDER, color());
Y = y() + OV_BORDER;
} else {
H = -H;
X = x() + w() - H + OV_BORDER;
Y = y() + h() - H;
if (OV_BORDER > 0)
fl_rectf(X, Y + H - OV_BORDER, H - OV_BORDER, OV_BORDER, color());
}
H -= OV_BORDER;
draw_box(box(), X, Y, H, H, color());
Fl_Rect r(X, Y, H, H);
Fl_Color arrow_color = fl_contrast(FL_GRAY_RAMP+0, color());
if (!active_r())
arrow_color = fl_inactive(arrow_color);
fl_draw_arrow(r, FL_ARROW_CHOICE, FL_ORIENT_NONE, arrow_color);
}
void Fl_Tabs::redraw_tabs() {
int H = tab_height();
if (H >= 0) {
damage(FL_DAMAGE_EXPOSE, x(), y(), w(), H + SELECTION_BORDER);
} else {
H = -H;
damage(FL_DAMAGE_EXPOSE, x(), y() + h() - H - SELECTION_BORDER, w(), H + SELECTION_BORDER);
}
}
int Fl_Tabs::handle(int event) {
static int initial_x = 0;
static int initial_tab_offset = 0;
static int forward_motion_to_group = 0;
static Fl_Widget *o_push_drag = NULL;
Fl_Widget *o;
int i;
switch (event) {
case FL_MOUSEWHEEL:
if ( ( (overflow_type == OVERFLOW_DRAG) || (overflow_type == OVERFLOW_PULLDOWN) )
&& hit_tabs_area(Fl::event_x(), Fl::event_y()) ) {
int original_tab_offset = tab_offset;
tab_offset -= 2 * Fl::event_dx();
if (tab_offset > 0)
tab_offset = 0;
int m = 0;
if (overflow_type == OVERFLOW_PULLDOWN) m = abs(tab_height());
int dw = tab_pos[children()] + tab_offset - w();
if (dw < -m)
tab_offset -= dw+m;
if (tab_offset != original_tab_offset)
redraw_tabs();
return 1;
}
return Fl_Group::handle(event);
case FL_PUSH:
initial_x = Fl::event_x();
initial_tab_offset = tab_offset;
forward_motion_to_group = 0;
if (hit_overflow_menu(Fl::event_x(), Fl::event_y())) {
handle_overflow_menu();
return 1;
}
if (!hit_tabs_area(Fl::event_x(), Fl::event_y())) {
forward_motion_to_group = 1;
}
case FL_DRAG:
o_push_drag = which(Fl::event_x(), Fl::event_y());
case FL_RELEASE:
if (forward_motion_to_group) {
return Fl_Group::handle(event);
}
o = which(Fl::event_x(), Fl::event_y());
if (event == FL_RELEASE && o != o_push_drag) { return 1;
}
if ( (overflow_type == OVERFLOW_DRAG) || (overflow_type == OVERFLOW_PULLDOWN) ) {
if (tab_pos[children()] < w() && tab_offset == 0) {
} else if (!Fl::event_is_click()) {
tab_offset = initial_tab_offset + Fl::event_x() - initial_x;
int m = 0;
if (overflow_type == OVERFLOW_PULLDOWN) m = abs(tab_height()) - OV_BORDER;
if (tab_offset > 0) {
initial_tab_offset -= tab_offset;
tab_offset = 0;
} else {
int dw = tab_pos[children()] + tab_offset - w();
if (dw < -m) {
initial_tab_offset -= dw+m;
tab_offset -= dw+m;
}
}
redraw_tabs();
return 1;
}
}
if (event == FL_RELEASE) {
push(0);
take_focus(o);
if (o && (o->when() & FL_WHEN_CLOSED) && hit_close(o, Fl::event_x(), Fl::event_y())) {
o->do_callback(FL_REASON_CLOSED);
return 1; }
maybe_do_callback(o);
} else {
push(o);
}
return 1;
case FL_MOVE: {
int ret = Fl_Group::handle(event);
Fl_Widget *tooltip_widget = Fl_Tooltip::current();
Fl_Widget *n; int H = tab_height();
if ( (H >= 0) && (Fl::event_y() > y()+H) )
return ret;
else if ( (H < 0) && (Fl::event_y() < y()+h()+H) )
return ret;
else {
n = which(Fl::event_x(), Fl::event_y());
if (!n) n = this;
}
if (n != tooltip_widget)
Fl_Tooltip::enter(n);
return ret; }
case FL_FOCUS:
case FL_UNFOCUS:
if (!Fl::visible_focus()) return Fl_Group::handle(event);
if (Fl::event() == FL_RELEASE ||
Fl::event() == FL_SHORTCUT ||
Fl::event() == FL_KEYBOARD ||
Fl::event() == FL_FOCUS ||
Fl::event() == FL_UNFOCUS) {
redraw_tabs();
if (Fl::event() == FL_FOCUS) return Fl_Group::handle(event);
if (Fl::event() == FL_UNFOCUS) return 0;
else return 1;
} else return Fl_Group::handle(event);
case FL_KEYBOARD:
switch (Fl::event_key()) {
case FL_Left:
if (!children()) return 0;
if (child(0)->visible()) return 0;
for (i = 1; i < children(); i ++)
if (child(i)->visible()) break;
value(child(i - 1));
set_changed();
do_callback(FL_REASON_SELECTED);
return 1;
case FL_Right:
if (!children()) return 0;
if (child(children() - 1)->visible()) return 0;
for (i = 0; i < children()-1; i++)
if (child(i)->visible()) break;
value(child(i + 1));
set_changed();
do_callback(FL_REASON_SELECTED);
return 1;
case FL_Down:
redraw();
return Fl_Group::handle(FL_FOCUS);
default:
break;
}
return Fl_Group::handle(event);
case FL_SHORTCUT:
for (i = 0; i < children(); ++i) {
Fl_Widget *c = child(i);
if (c->test_shortcut(c->label())) {
char sc = !c->visible();
value(c);
if (sc) {
set_changed();
do_callback(FL_REASON_SELECTED);
} else {
do_callback(FL_REASON_RESELECTED);
}
return 1;
}
}
return Fl_Group::handle(event);
case FL_SHOW:
value(); default:
return Fl_Group::handle(event);
}
}
int Fl_Tabs::push(Fl_Widget *o) {
if (push_ == o) return 0;
if ( (push_ && !push_->visible()) || (o && !o->visible()) )
redraw_tabs();
push_ = o;
return 1;
}
Fl_Widget* Fl_Tabs::value() {
Fl_Widget* v = 0;
Fl_Widget*const* a = array();
for (int i=children(); i--;) {
Fl_Widget* o = *a++;
if (v) o->hide();
else if (o->visible()) v = o;
else if (!i) {o->show(); v = o;}
}
return v;
}
int Fl_Tabs::value(Fl_Widget *newvalue) {
Fl_Widget*const* a = array();
int ret = 0;
int selected = -1;
for (int i=children(); i--;) {
Fl_Widget* o = *a++;
if (o == newvalue) {
if (!o->visible()) ret = 1;
o->show();
selected = children()-i-1;
} else {
o->hide();
}
}
if ( (selected >= 0)
&& ( (overflow_type == OVERFLOW_DRAG)
|| (overflow_type == OVERFLOW_PULLDOWN) ) ) {
int m = MARGIN;
if ( (selected == 0) || (selected == children()-1) ) m = BORDER;
int mr = m;
tab_positions();
if (overflow_type == OVERFLOW_PULLDOWN) mr += abs(tab_height() - OV_BORDER);
if (tab_pos[selected]+tab_width[selected]+tab_offset+mr > w()) {
tab_offset = w() - tab_pos[selected] - tab_width[selected] - mr;
} else if (tab_pos[selected]+tab_offset-m < 0) {
tab_offset = -tab_pos[selected]+m;
}
}
redraw_tabs();
return ret;
}
void Fl_Tabs::draw() {
if (children() == 0) {
fl_rectf(x(), y(), w(), h(), color());
if (align() & FL_ALIGN_INSIDE)
draw_label();
clear_damage();
return;
}
Fl_Widget *selected_child = value(); tab_positions();
int selected = find(selected_child); if (selected == children()) selected = -1; int H = tab_height();
Fl_Color selected_tab_color = selected_child ? selected_child->color() : color();
bool tabs_at_top = (H > 0);
bool colored_selection_border = (selection_color() != selected_tab_color);
int tabs_y, tabs_h;
int child_area_y, child_area_h;
int clipped_child_area_y, clipped_child_area_h;
int selection_border_y, selection_border_h;
selection_border_h = colored_selection_border ? SELECTION_BORDER : Fl::box_dx(box());
if (tabs_at_top) {
tabs_h = H;
tabs_y = y();
selection_border_y = y() + tabs_h;
child_area_y = y() + tabs_h;
child_area_h = h() - tabs_h;
clipped_child_area_y = y() + tabs_h + selection_border_h;
clipped_child_area_h = h() - tabs_h - selection_border_h;
} else {
tabs_h = -H;
tabs_y = y() + h() - tabs_h;
selection_border_y = tabs_y - selection_border_h;
child_area_y = y();
child_area_h = h() - tabs_h;
clipped_child_area_y = y();
clipped_child_area_h = h() - tabs_h - selection_border_h;
}
if (damage() & (FL_DAMAGE_ALL|FL_DAMAGE_SCROLL)) {
Fl_Widget *selected_tab = value();
if (selected_tab)
value(selected_tab);
}
if (damage() & (FL_DAMAGE_ALL|FL_DAMAGE_EXPOSE|FL_DAMAGE_SCROLL))
{
if (parent()) {
Fl_Widget *p = parent();
fl_push_clip(x(), tabs_y, w(), tabs_h);
if (Fl_Window *win = p->as_window()) {
fl_draw_box(p->box(), 0, 0, p->w(), p->h(), p->color());
win->draw_backdrop();
} else {
fl_draw_box(p->box(), p->x(), p->y(), p->w(), p->h(), p->color());
}
fl_pop_clip();
} else {
fl_rectf(x(), tabs_y, w(), tabs_h, color());
}
fl_push_clip(x(), selection_border_y, w(), selection_border_h);
if (colored_selection_border) {
draw_box(box(), x(), y(), w(), h(), selected_tab_color);
draw_box(box(), x(), selection_border_y, w(), selection_border_h, selection_color());
} else {
draw_box(box(), x(), child_area_y, w(), child_area_h, selected_tab_color);
}
if (selected != -1) {
int stem_x = x() + tab_pos[selected] + tab_offset;
int stem_w = fl_min(tab_pos[selected+1] - tab_pos[selected], tab_width[selected]);
if (colored_selection_border) {
if (tabs_at_top)
fl_rectf(stem_x, selection_border_y, stem_w, selection_border_h/2, selection_color());
else
fl_rectf(stem_x, selection_border_y+selection_border_h-selection_border_h/2, stem_w, selection_border_h/2, selection_color());
} else {
fl_rectf(stem_x, child_area_y-tabs_h, stem_w, child_area_h+2*tabs_h, selection_color());
}
}
fl_pop_clip();
fl_push_clip(x(), tabs_y, w(), tabs_h);
int i, clip_left, clip_right;
int safe_selected = selected == -1 ? children() : selected;
clip_left = x();
for (i=0; i<safe_selected; i++) {
clip_right = (i<tab_count-1) ? x()+(tab_offset+tab_pos[i+1]+tab_width[i+1]/2) : x() + w();
fl_push_clip(clip_left, tabs_y, clip_right-clip_left, tabs_h);
draw_tab(x()+tab_pos[i], x()+tab_pos[i+1],
tab_width[i], H, child(i), tab_flags[i], LEFT);
fl_pop_clip();
}
clip_right = x() + w();
for (i=children()-1; i > safe_selected; i--) {
clip_left = (i>0) ? (tab_offset+tab_pos[i]-tab_width[i-1]/2) : x();
fl_push_clip(clip_left, tabs_y, clip_right-clip_left, tabs_h);
draw_tab(x()+tab_pos[i], x()+tab_pos[i+1],
tab_width[i], H, child(i), tab_flags[i], RIGHT);
fl_pop_clip();
}
if (selected > -1)
draw_tab(x()+tab_pos[selected], x()+tab_pos[selected+1],
tab_width[selected], H, selected_child, tab_flags[selected], SELECTED);
fl_pop_clip();
if (overflow_type == OVERFLOW_PULLDOWN)
check_overflow_menu();
if (has_overflow_menu)
draw_overflow_menu_button();
}
if (damage() & (FL_DAMAGE_ALL|FL_DAMAGE_CHILD)) {
fl_push_clip(x(), clipped_child_area_y, w(), clipped_child_area_h);
if (damage() & (FL_DAMAGE_ALL)) {
if (colored_selection_border)
draw_box(box(), x(), y(), w(), h(), selected_tab_color);
else
draw_box(box(), x(), child_area_y, w(), child_area_h, selected_tab_color);
if (selected_child)
draw_child(*selected_child);
} else if (damage() & (FL_DAMAGE_CHILD)) {
if (selected_child)
update_child(*selected_child);
}
fl_pop_clip();
}
clear_damage();
}
void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int flags, int what) {
x1 += tab_offset;
x2 += tab_offset;
int sel = (what == SELECTED);
int dh = Fl::box_dh(box());
int wc = 0; char prev_draw_shortcut = fl_draw_shortcut;
fl_draw_shortcut = 1;
Fl_Boxtype bt = (o == push_ && !sel) ? fl_down(box()) : box();
Fl_Color bc = sel ? selection_color() : o->selection_color();
Fl_Color oc = o->labelcolor();
Fl_Labeltype ot = o->labeltype();
if (ot == FL_NO_LABEL)
o->labeltype(FL_NORMAL_LABEL);
int yofs = sel ? 0 : BORDER;
if ((x2 < x1+W) && what == RIGHT) x1 = x2 - W;
if (H >= 0) {
H += dh;
draw_box(bt, x1, y() + yofs, W, H + 10 - yofs, bc);
o->labelcolor(sel ? labelcolor() : o->labelcolor());
if ( (o->when() & FL_WHEN_CLOSED) && !(flags & 1) ) {
int sz = labelsize()/2, sy = (H - sz)/2;
Fl_Color close_color = fl_contrast(FL_GRAY_RAMP+0, bc);
if (!active_r())
close_color = fl_inactive(close_color);
fl_draw_symbol("@3+", x1 + EXTRASPACE/2, y() + yofs/2 + sy, sz, sz, close_color);
wc = sz + EXTRAGAP;
}
o->draw_label(x1 + wc, y() + yofs, W - wc, H - yofs, tab_align());
if (Fl::focus() == this && o->visible())
draw_focus(bt, x1, y(), W, H, bc);
} else {
H = -H;
H += dh;
draw_box(bt, x1, y() + h() - H - 10, W, H + 10 - yofs, bc);
o->labelcolor(sel ? labelcolor() : o->labelcolor());
if ( (o->when() & FL_WHEN_CLOSED) && (x1+W < x2) ) {
int sz = labelsize()/2, sy = (H - sz)/2;
Fl_Color close_color = fl_contrast(FL_GRAY_RAMP+0, bc);
if (!active_r())
close_color = fl_inactive(close_color);
fl_draw_symbol("@3+", x1 + EXTRASPACE/2, y() + h() - H -yofs/2 + sy, sz, sz, close_color);
wc = sz + EXTRAGAP;
}
o->draw_label(x1 + wc, y() + h() - H, W - wc, H - yofs, tab_align());
if (Fl::focus() == this && o->visible())
draw_focus(bt, x1, y()+h()-H+1, W, H, bc);
}
fl_draw_shortcut = prev_draw_shortcut;
o->labelcolor(oc);
o->labeltype(ot);
}
Fl_Tabs::Fl_Tabs(int X, int Y, int W, int H, const char *L) :
Fl_Group(X,Y,W,H,L)
{
box(FL_THIN_UP_BOX);
push_ = 0;
overflow_type = OVERFLOW_COMPRESS;
tab_offset = 0;
tab_pos = 0;
tab_width = 0;
tab_flags = NULL;
tab_count = 0;
tab_align_ = FL_ALIGN_CENTER;
has_overflow_menu = 0;
}
Fl_Tabs::~Fl_Tabs() {
clear_tab_positions();
}
void Fl_Tabs::client_area(int &rx, int &ry, int &rw, int &rh, int tabh) {
if (children()) {
rx = child(0)->x();
ry = child(0)->y();
rw = child(0)->w();
rh = child(0)->h();
} else {
int y_offset;
int label_height = fl_height(labelfont(), labelsize()) + BORDER*2;
if (tabh == 0) y_offset = label_height;
else if (tabh == -1) y_offset = -label_height;
else
y_offset = tabh;
rx = x();
rw = w();
if (y_offset >= 0) { ry = y() + y_offset;
rh = h() - y_offset;
} else { 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;
}
if (tab_flags){
free(tab_flags);
tab_flags = NULL;
}
}
void Fl_Tabs::handle_overflow(int ov) {
overflow_type = ov;
tab_offset = 0;
has_overflow_menu = 0;
damage(FL_DAMAGE_SCROLL);
redraw();
}