diff --git a/FL/Fl_Tabs.H b/FL/Fl_Tabs.H index 2b1d97ca9..961d3b77f 100644 --- a/FL/Fl_Tabs.H +++ b/FL/Fl_Tabs.H @@ -251,6 +251,8 @@ protected: Fl_Align tab_align_; ///< tab label alignment int has_overflow_menu;///< set in OVERFLOW_PULLDOWN mode if tabs overflow. The actual menu array is created only on demand + void take_focus(Fl_Widget *o); + void maybe_do_callback(Fl_Widget *o); void check_overflow_menu(); void handle_overflow_menu(); void draw_overflow_menu_button(); diff --git a/src/Fl_Tabs.cxx b/src/Fl_Tabs.cxx index ed6b45a5c..f47cbc240 100644 --- a/src/Fl_Tabs.cxx +++ b/src/Fl_Tabs.cxx @@ -374,6 +374,35 @@ void Fl_Tabs::check_overflow_menu() { } } +/** + Take keyboard focus if o is not NULL. + \param[in] o selected tab + */ +void Fl_Tabs::take_focus(Fl_Widget *o) { + if (o && Fl::visible_focus() && Fl::focus()!=this) { + Fl::focus(this); + redraw_tabs(); + } +} + +/** + Set tab o as selected an call callbacks if needed. + \param[in] o the newly selected tab + */ +void Fl_Tabs::maybe_do_callback(Fl_Widget *o) { + if (o && // Released on a tab and.. + (value(o) || // tab changed value or.. + (when()&(FL_WHEN_NOT_CHANGED)) // ..no change but WHEN_NOT_CHANGED set, + ) // handles FL_WHEN_RELEASE_ALWAYS too. + ) { + Fl_Widget_Tracker wp(o); + set_changed(); + do_callback(FL_REASON_SELECTED); + if (wp.deleted()) return; + } + return; +} + /** This is called when the user clicks the overflow pulldown menu button. @@ -414,8 +443,13 @@ void Fl_Tabs::handle_overflow_menu() { // show the menu and handle the selection const Fl_Menu_Item *m = overflow_menu->popup(x()+w()-H, (tab_height()>0)?(y()+H):(y()+h())); - if (m) - value((Fl_Widget*)m->user_data()); + if (m) { + Fl_Widget *o = (Fl_Widget*)m->user_data(); + push(0); + take_focus(o); + maybe_do_callback(o); + Fl_Tooltip::current(o); + } // delete the menu until we need it next time if (overflow_menu) { @@ -532,24 +566,12 @@ int Fl_Tabs::handle(int event) { } if (event == FL_RELEASE) { push(0); - if (o && Fl::visible_focus() && Fl::focus()!=this) { - Fl::focus(this); - redraw_tabs(); - } + 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; // o may be deleted at this point } - if (o && // Released on a tab and.. - (value(o) || // tab changed value or.. - (when()&(FL_WHEN_NOT_CHANGED)) // ..no change but WHEN_NOT_CHANGED set, - ) // handles FL_WHEN_RELEASE_ALWAYS too. - ) { - Fl_Widget_Tracker wp(o); - set_changed(); - do_callback(FL_REASON_SELECTED); - if (wp.deleted()) return 1; - } + maybe_do_callback(o); Fl_Tooltip::current(o); } else { push(o); diff --git a/test/tabs.fl b/test/tabs.fl index 25a610b9d..78c9b9da8 100644 --- a/test/tabs.fl +++ b/test/tabs.fl @@ -12,7 +12,13 @@ Function {} {open label {class Fl_Tabs} xywh {95 0 130 35} labeltype ENGRAVED_LABEL labelfont 1 } - Fl_Tabs tabs_group {open + Fl_Tabs tabs_group { + callback {Fl_Widget *sel_tab = o->value(); +if (sel_tab) { + printf("Callback called for tab \\"%s\\"\\n", sel_tab->label()); +} else { + printf("Callback called\\n"); +}} open selected tooltip {the various index cards test different aspects of the Fl_Tabs widget} xywh {10 35 315 260} selection_color 4 labelcolor 7 resizable code0 {// tabs_group->handle_overflow(Fl_Tabs::OVERFLOW_PULLDOWN);} } { @@ -159,7 +165,7 @@ Function {} {open } } Fl_Group {} { - label tab2 selected + label tab2 tooltip {tab2 tests among other things the cooperation of modal windows and tabs} xywh {330 60 320 235} selection_color 2 } { Fl_Button {} {