diff options
author | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2010-08-20 23:24:19 +0200 |
---|---|---|
committer | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2010-08-20 23:24:19 +0200 |
commit | f5c598b518d1f906148534d015f50075d3e8242d (patch) | |
tree | 21dd70add5b366c3dd80641b77f6b18e0baa009e /src/ui.cc | |
parent | e98d02a01ffeb18ede86af025e51ae1ec011c75a (diff) | |
parent | 5f0fc0e48b8cbee7e1795935da0abff6627fd498 (diff) |
merge
Diffstat (limited to 'src/ui.cc')
-rw-r--r-- | src/ui.cc | 375 |
1 files changed, 223 insertions, 152 deletions
@@ -11,7 +11,7 @@ // UI for Dillo -#include <stdlib.h> +#include <unistd.h> #include <stdio.h> #include <fltk/HighlightButton.h> @@ -25,9 +25,11 @@ #include <fltk/Item.h> #include <fltk/Divider.h> +#include "keys.hh" #include "ui.hh" #include "msg.h" #include "timeout.hh" +#include "utf8.hh" using namespace fltk; @@ -38,8 +40,9 @@ using namespace fltk; struct iconset { Image *ImgMeterOK, *ImgMeterBug, - *ImgHome, *ImgReload, *ImgSave, *ImgBook, *ImgClear, *ImgSearch; - MultiImage *ImgLeftMulti, *ImgRightMulti, *ImgStopMulti, *ImgImageLoadMulti; + *ImgHome, *ImgReload, *ImgSave, *ImgBook, *ImgTools, + *ImgClear,*ImgSearch, *ImgHelp; + MultiImage *ImgLeftMulti, *ImgRightMulti, *ImgStopMulti; }; static struct iconset standard_icons = { @@ -49,16 +52,16 @@ static struct iconset standard_icons = { new xpmImage(reload_xpm), new xpmImage(save_xpm), new xpmImage(bm_xpm), + new xpmImage(tools_xpm), new xpmImage(new_s_xpm), new xpmImage(search_xpm), + new xpmImage(help_xpm), new MultiImage(*new xpmImage(left_xpm), INACTIVE_R, *new xpmImage(left_i_xpm)), new MultiImage(*new xpmImage(right_xpm), INACTIVE_R, *new xpmImage(right_i_xpm)), new MultiImage(*new xpmImage(stop_xpm), INACTIVE_R, *new xpmImage(stop_i_xpm)), - new MultiImage(*new xpmImage(imgload_off_xpm), STATE, - *new xpmImage(imgload_on_xpm)) }; static struct iconset small_icons = { @@ -68,15 +71,16 @@ static struct iconset small_icons = { new xpmImage(reload_s_xpm), new xpmImage(save_s_xpm), new xpmImage(bm_s_xpm), + new xpmImage(tools_s_xpm), new xpmImage(new_s_xpm), standard_icons.ImgSearch, + standard_icons.ImgHelp, new MultiImage(*new xpmImage(left_s_xpm), INACTIVE_R, *new xpmImage(left_si_xpm)), new MultiImage(*new xpmImage(right_s_xpm), INACTIVE_R, *new xpmImage(right_si_xpm)), new MultiImage(*new xpmImage(stop_s_xpm), INACTIVE_R, *new xpmImage(stop_si_xpm)), - standard_icons.ImgImageLoadMulti }; @@ -99,7 +103,7 @@ public: }; /* - * Disable: UpKey, DownKey, PageUpKey, PageDownKey and + * Disable: UpKey, DownKey, PageUpKey, PageDownKey and * CTRL+{o,r,HomeKey,EndKey} */ int CustInput::handle(int e) @@ -167,11 +171,11 @@ int CustHighlightButton::handle(int e) * Used to resize the progress boxes automatically. */ class CustProgressBox : public InvisibleBox { + int padding; public: CustProgressBox(int x, int y, int w, int h, const char *l=0) : - InvisibleBox(x,y,w,h,l) {}; + InvisibleBox(x,y,w,h,l) { padding = 0; }; void update_label(const char *lbl) { - static int padding = 0; int w,h; if (!padding) { copy_label("W"); @@ -189,7 +193,7 @@ public: // Toolbar buttons ----------------------------------------------------------- // //static const char *button_names[] = { -// "Back", "Forward", "Home", "Reload", "Save", "Stop", "Bookmarks", +// "Back", "Forward", "Home", "Reload", "Save", "Stop", "Bookmarks", "Tools", // "Clear", "Search" //}; @@ -215,6 +219,26 @@ static void search_cb(Widget *wid, void *data) } /* + * Callback for the help button. + */ +static void help_cb(Widget *w, void *) +{ + char *path = dStrconcat(DILLO_DOCDIR, "user_help.html", NULL); + BrowserWindow *bw = a_UIcmd_get_bw_by_widget(w); + + if (access(path, R_OK) == 0) { + char *urlstr = dStrconcat("file:", path, NULL); + a_UIcmd_open_urlstr(bw, urlstr); + dFree(urlstr); + } else { + MSG("Can't read local help file at \"%s\"." + " Getting remote help...\n", path); + a_UIcmd_open_urlstr(bw, "http://www.dillo.org/dillo2-help.html"); + } + dFree(path); +} + +/* * Callback for the File menu button. */ static void filemenu_cb(Widget *wid, void *) @@ -324,6 +348,11 @@ static void b1_cb(Widget *wid, void *cb_data) a_UIcmd_book(a_UIcmd_get_bw_by_widget(wid)); } break; + case UI_TOOLS: + if (k == 1 || k == 3) { + a_UIcmd_tools(a_UIcmd_get_bw_by_widget(wid), wid); + } + break; default: break; } @@ -370,50 +399,58 @@ PackedGroup *UI::make_toolbar(int tw, int th) p1->begin(); Back = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Back" : 0); b->image(icons->ImgLeftMulti); - b->tooltip("Previous page"); b->callback(b1_cb, (void *)UI_BACK); b->clear_tab_to_focus(); HighlightButton::default_style->highlight_color(CuteColor); Forw = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Forw" : 0); b->image(icons->ImgRightMulti); - b->tooltip("Next page"); b->callback(b1_cb, (void *)UI_FORW); b->clear_tab_to_focus(); - + Home = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Home" : 0); b->image(icons->ImgHome); - b->tooltip("Go to the Home page"); b->callback(b1_cb, (void *)UI_HOME); b->clear_tab_to_focus(); Reload = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Reload" : 0); b->image(icons->ImgReload); - b->tooltip("Reload"); b->callback(b1_cb, (void *)UI_RELOAD); b->clear_tab_to_focus(); - + Save = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Save" : 0); b->image(icons->ImgSave); - b->tooltip("Save this page"); b->callback(b1_cb, (void *)UI_SAVE); b->clear_tab_to_focus(); - + Stop = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Stop" : 0); b->image(icons->ImgStopMulti); - b->tooltip("Stop loading"); b->callback(b1_cb, (void *)UI_STOP); b->clear_tab_to_focus(); Bookmarks = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Book" : 0); b->image(icons->ImgBook); - b->tooltip("View bookmarks"); b->callback(b1_cb, (void *)UI_BOOK); b->clear_tab_to_focus(); + Tools = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Tools" : 0); + b->image(icons->ImgTools); + b->callback(b1_cb, (void *)UI_TOOLS); + b->clear_tab_to_focus(); + p1->type(PackedGroup::ALL_CHILDREN_VERTICAL); p1->end(); + if (prefs.show_tooltip) { + Back->tooltip("Previous page"); + Forw->tooltip("Next page"); + Home->tooltip("Go to the Home page"); + Reload->tooltip("Reload"); + Save->tooltip("Save this page"); + Stop->tooltip("Stop loading"); + Bookmarks->tooltip("View bookmarks"); + Tools->tooltip("Settings"); + } return p1; } @@ -427,12 +464,10 @@ PackedGroup *UI::make_location() pg->begin(); Clear = b = new CustHighlightButton(2,2,16,22,0); b->image(icons->ImgClear); - b->tooltip("Clear the URL box.\nMiddle-click to paste a URL."); b->callback(clear_cb, this); b->clear_tab_to_focus(); Input *i = Location = new CustInput(0,0,0,0,0); - i->tooltip("Location"); i->color(CuteColor); i->when(WHEN_ENTER_KEY); i->callback(location_cb, this); @@ -440,14 +475,24 @@ PackedGroup *UI::make_location() Search = b = new HighlightButton(0,0,16,22,0); b->image(icons->ImgSearch); - b->tooltip("Search the Web"); b->callback(search_cb, this); b->clear_tab_to_focus(); + Help = b = new HighlightButton(0,0,16,22,0); + b->image(icons->ImgHelp); + b->callback(help_cb, this); + b->clear_tab_to_focus(); + pg->type(PackedGroup::ALL_CHILDREN_VERTICAL); pg->resizable(i); pg->end(); + if (prefs.show_tooltip) { + Clear->tooltip("Clear the URL box.\nMiddle-click to paste a URL."); + Location->tooltip("Location"); + Search->tooltip("Search the Web"); + Help->tooltip("Help"); + } return pg; } @@ -494,7 +539,8 @@ Widget *UI::make_filemenu_button() _MSG("UI::make_filemenu_button w=%d h=%d padding=%d\n", w, h, padding); btn->box(PanelSize == P_large ? FLAT_BOX : THIN_UP_BOX); btn->callback(filemenu_cb, this); - btn->tooltip("File menu"); + if (prefs.show_tooltip) + btn->tooltip("File menu"); btn->clear_tab_to_focus(); if (!prefs.show_filemenu && PanelSize != P_large) btn->hide(); @@ -520,7 +566,7 @@ Group *UI::make_panel(int ww) icons = &small_icons; else icons = &standard_icons; - + if (PanelSize == P_tiny) { if (Small_Icons) xpos = 0, bw = 22, bh = 22, fh = 0, lh = 22, lbl = 0; @@ -584,7 +630,7 @@ Group *UI::make_panel(int ww) g2->resizable(pg); g2->end(); - + // Toolbar g3 = new Group(0,fh+lh,ww,bh); g3->begin(); @@ -600,12 +646,12 @@ Group *UI::make_panel(int ww) w = make_progress_bars(1,0); } pg->add(w); - + g3->resizable(pg); // Better than 'w3' and it also works pg->box(BORDER_FRAME); //g3->box(EMBOSSED_BOX); g3->end(); - + g1->resizable(g3); g1->end(); } @@ -614,16 +660,45 @@ Group *UI::make_panel(int ww) } /* + * Create the status panel + */ +Group *UI::make_status_panel(int ww) +{ + const int s_h = 20, bm_w = 16; + Group *g = new Group(0, 0, ww, s_h, 0); + + // Status box + Status = new Output(0, 0, ww-bm_w, s_h, 0); + Status->value(""); + Status->box(THIN_DOWN_BOX); + Status->clear_click_to_focus(); + Status->clear_tab_to_focus(); + Status->color(GRAY80); + g->add(Status); + //Status->throw_focus(); + + // Bug Meter + BugMeter = new HighlightButton(ww-bm_w,0,bm_w,s_h,0); + BugMeter->image(icons->ImgMeterOK); + BugMeter->box(THIN_DOWN_BOX); + BugMeter->align(ALIGN_INSIDE|ALIGN_CLIP|ALIGN_LEFT); + if (prefs.show_tooltip) + BugMeter->tooltip("Show HTML bugs\n(right-click for menu)"); + BugMeter->callback(bugmeter_cb, this); + BugMeter->clear_tab_to_focus(); + g->add(BugMeter); + + g->resizable(Status); + return g; +} + +/* * User Interface constructor - */ + */ UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) : Group(x, y, ww, wh, label) { - int s_h = 20; - - Font *f = font(prefs.vw_fontname, 0); - if (f) - this->labelfont(f); + PointerOnLink = FALSE; Tabs = NULL; TabTooltip = NULL; @@ -631,12 +706,16 @@ UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) : add(TopGroup); resizable(TopGroup); set_flag(RAW_LABEL); - + if (cur_ui) { PanelSize = cur_ui->PanelSize; CuteColor = cur_ui->CuteColor; Small_Icons = cur_ui->Small_Icons; - Panelmode = cur_ui->Panelmode; + if (cur_ui->Panelmode == UI_HIDDEN || + cur_ui->Panelmode == UI_TEMPORARILY_SHOW_PANELS) + Panelmode = UI_HIDDEN; + else + Panelmode = UI_NORMAL; } else { // Set some default values //PanelSize = P_tiny, CuteColor = 26, Small_Icons = 0; @@ -646,12 +725,10 @@ UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) : Panelmode = (UIPanelmode) prefs.fullwindow_start; } - // Control panel Panel = make_panel(ww); TopGroup->add(Panel); - // Render area Main = new Widget(0,0,1,1,"Welcome..."); Main->box(FLAT_BOX); @@ -666,47 +743,11 @@ UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) : // Find text bar findbar = new Findbar(ww, 28); - TopGroup->add(findbar); + TopGroup->add(findbar); // Status Panel - StatusPanel = new Group(0, 0, ww, s_h, 0); - // Status box - int il_w = 16; - int bm_w = 16; - Status = new Output(0, 0, ww-bm_w-il_w, s_h, 0); - Status->value(""); - Status->box(THIN_DOWN_BOX); - Status->clear_click_to_focus(); - Status->clear_tab_to_focus(); - Status->color(GRAY80); - StatusPanel->add(Status); - //Status->throw_focus(); - - // Image loading indicator - ImageLoad = new HighlightButton(ww-il_w-bm_w,0,il_w,s_h,0); - ImageLoad->type(Button::TOGGLE); - ImageLoad->state(prefs.load_images); - ImageLoad->image(icons->ImgImageLoadMulti); - - ImageLoad->box(THIN_DOWN_BOX); - ImageLoad->align(ALIGN_INSIDE|ALIGN_CLIP|ALIGN_LEFT); - ImageLoad->tooltip("Toggle image loading"); - ImageLoad->clear_tab_to_focus(); - StatusPanel->add(ImageLoad); - - // Bug Meter - BugMeter = new HighlightButton(ww-bm_w,0,bm_w,s_h,0); - BugMeter->image(icons->ImgMeterOK); - BugMeter->box(THIN_DOWN_BOX); - BugMeter->align(ALIGN_INSIDE|ALIGN_CLIP|ALIGN_LEFT); - BugMeter->tooltip("Show HTML bugs\n(right-click for menu)"); - BugMeter->callback(bugmeter_cb, this); - BugMeter->clear_tab_to_focus(); - StatusPanel->add(BugMeter); - - StatusPanel->resizable(Status); - - TopGroup->add(StatusPanel); + StatusPanel = make_status_panel(ww); + TopGroup->add(StatusPanel); // Make the full screen button (to be attached to the viewport later) // TODO: attach to the viewport @@ -721,8 +762,6 @@ UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) : Panel->hide(); StatusPanel->hide(); } - - //show(); } /* @@ -742,69 +781,102 @@ int UI::handle(int event) _MSG("UI::handle event=%d (%d,%d)\n", event, event_x(), event_y()); _MSG("Panel->h()=%d Main->h()=%d\n", Panel->h() , Main->h()); - int ret = 0, k = event_key(); - - // We're only interested in some flags - unsigned modifier = event_state() & (SHIFT | CTRL | ALT); + int ret = 0; if (event == KEY) { return 0; // Receive as shortcut - } else if (event == SHORTCUT) { - // Handle keyboard shortcuts here. - if (modifier == CTRL) { - if (k == 'b') { - a_UIcmd_book(a_UIcmd_get_bw_by_widget(this)); - ret = 1; - } else if (k == 'f') { - set_findbar_visibility(1); - ret = 1; - } else if (k == 'l') { - focus_location(); - ret = 1; - } else if (k == 'n') { - a_UIcmd_browser_window_new(w(),h(),a_UIcmd_get_bw_by_widget(this)); - ret = 1; - } else if (k == 'o') { - a_UIcmd_open_file(a_UIcmd_get_bw_by_widget(this)); - ret = 1; - } else if (k == 'q') { - a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(this)); - ret = 1; - } else if (k == 'r') { - a_UIcmd_reload(a_UIcmd_get_bw_by_widget(this)); - ret = 1; - } else if (k == 's') { - a_UIcmd_search_dialog(a_UIcmd_get_bw_by_widget(this)); - ret = 1; - } else if (k == 't') { - a_UIcmd_open_url_nt(a_UIcmd_get_bw_by_widget(this), NULL, 1); - ret = 1; - } else if (k == ' ') { - panelmode_cb_i(); - ret = 1; - } - } else if (modifier == ALT) { - if (k == 'f') { - a_UIcmd_file_popup(a_UIcmd_get_bw_by_widget(this), FileButton); - } else if (k == 'q' && event_key_state(LeftAltKey)) { - a_Timeout_add(0.0, a_UIcmd_close_all_bw, NULL); + KeysCommand_t cmd = Keys::getKeyCmd(); + if (cmd == KEYS_NOP) { + // Do nothing + } else if (cmd == KEYS_SCREEN_UP || cmd == KEYS_SCREEN_DOWN || + cmd == KEYS_LINE_UP || cmd == KEYS_LINE_DOWN || + cmd == KEYS_LEFT || cmd == KEYS_RIGHT || + cmd == KEYS_TOP || cmd == KEYS_BOTTOM) { + a_UIcmd_scroll(a_UIcmd_get_bw_by_widget(this), cmd); + ret = 1; + } else if (cmd == KEYS_BACK) { + a_UIcmd_back(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_FORWARD) { + a_UIcmd_forw(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_BOOKMARKS) { + a_UIcmd_book(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_FIND) { + set_findbar_visibility(1); + ret = 1; + } else if (cmd == KEYS_WEBSEARCH) { + a_UIcmd_search_dialog(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_GOTO) { + focus_location(); + ret = 1; + } else if (cmd == KEYS_NEW_TAB) { + a_UIcmd_open_url_nt(a_UIcmd_get_bw_by_widget(this), NULL, 1); + ret = 1; + } else if (cmd == KEYS_CLOSE_TAB) { + a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_HIDE_PANELS && + get_panelmode() == UI_TEMPORARILY_SHOW_PANELS) { + set_panelmode(UI_HIDDEN); + ret = 1; + } else if (cmd == KEYS_NEW_WINDOW) { + a_UIcmd_browser_window_new(w(),h(),0,a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_OPEN) { + a_UIcmd_open_file(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_HOME) { + a_UIcmd_home(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_RELOAD) { + a_UIcmd_reload(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_STOP) { + a_UIcmd_stop(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_SAVE) { + a_UIcmd_save(a_UIcmd_get_bw_by_widget(this)); + ret = 1; + } else if (cmd == KEYS_FULLSCREEN) { + panelmode_cb_i(); + ret = 1; + } else if (cmd == KEYS_FILE_MENU) { + a_UIcmd_file_popup(a_UIcmd_get_bw_by_widget(this), FileButton); + ret = 1; + } else if (cmd == KEYS_CLOSE_ALL) { + a_Timeout_add(0.0, a_UIcmd_close_all_bw, NULL); + ret = 1; + } + } else if (event == PUSH) { + if (prefs.middle_click_drags_page == 0 && + event_button() == MiddleButton && + !a_UIcmd_pointer_on_link(a_UIcmd_get_bw_by_widget(this))) { + if (Main->Rectangle::contains (event_x (), event_y ())) { + /* Offer the event to Main's children (form widgets) */ + int save_x = e_x, save_y = e_y; + + e_x -= Main->x(); + e_y -= Main->y(); + ret = ((Group *)Main)->Group::handle(event); + e_x = save_x; + e_y = save_y; } - } else { - // Back and Forward navigation shortcuts - if (modifier == 0 && (k == BackSpaceKey || k == ',')) { - a_UIcmd_back(a_UIcmd_get_bw_by_widget(this)); - ret = 1; - } else if ((modifier == 0 && k == '.') || - (modifier == SHIFT && k == BackSpaceKey)) { - a_UIcmd_forw(a_UIcmd_get_bw_by_widget(this)); + if (!ret) { + /* middle click was not on a link or a form widget */ + paste_url(); ret = 1; } } } - if (!ret) + if (!ret) { ret = Group::handle(event); + } + return ret; } @@ -898,7 +970,7 @@ void UI::set_img_prog(int n_img, int t_img, int cmd) } else { IProg->activate(); if (cmd == 1) { - snprintf(str, 32, "%s%d of %d", + snprintf(str, 32, "%s%d of %d", (PanelSize == 0) ? "" : "Images\n", n_img, t_img); } else if (cmd == 2) { str[0] = '\0'; @@ -926,9 +998,7 @@ void UI::set_bug_prog(int n_bug) BugMeter->redraw_label(); new_w = strlen(str)*8 + 20; } - Status->resize(0,0,StatusPanel->w()-ImageLoad->w()-new_w,Status->h()); - ImageLoad->resize(StatusPanel->w()-ImageLoad->w()-new_w, 0, ImageLoad->w(), - ImageLoad->h()); + Status->resize(0,0,StatusPanel->w()-new_w,Status->h()); BugMeter->resize(StatusPanel->w()-new_w, 0, new_w, BugMeter->h()); StatusPanel->init_sizes(); } @@ -954,12 +1024,16 @@ void UI::customize(int flags) Stop->hide(); if ( !prefs.show_bookmarks ) Bookmarks->hide(); + if ( !prefs.show_tools ) + Tools->hide(); if ( !prefs.show_clear_url ) Clear->hide(); if ( !prefs.show_url ) Location->hide(); if ( !prefs.show_search ) Search->hide(); + if ( !prefs.show_help ) + Help->hide(); if ( !prefs.show_progress_box ) ProgBox->hide(); } @@ -987,7 +1061,8 @@ void UI::panel_cb_i() */ void UI::color_change_cb_i() { - static int ncolor = 0, cols[] = {7,17,26,51,140,156,205,206,215,-1}; + const int cols[] = {7,17,26,51,140,156,205,206,215,-1}; + static int ncolor = 0; ncolor = (cols[ncolor+1] < 0) ? 0 : ncolor + 1; CuteColor = cols[ncolor]; @@ -1048,32 +1123,28 @@ void UI::set_render_layout(Widget &nw) } /* - * Set the window title + * Set the tab title */ -void UI::set_page_title(const char *label) +void UI::set_tab_title(const char *label) { char title[128]; dReturn_if_fail(label != NULL); - snprintf(title, 128, "Dillo: %s", label); - this->window()->copy_label(title); - this->window()->redraw_label(); + if (*label) { + // Make a label for this tab + size_t tab_chars = 18, label_len = strlen(label); - if (tabs() && *label) { - size_t tab_chars = 18; + if (label_len > tab_chars) + tab_chars = a_Utf8_end_of_char(label, tab_chars - 1) + 1; snprintf(title, tab_chars + 1, "%s", label); - if (strlen(label) > tab_chars) { - while (label[tab_chars] & 0x80 && !(label[tab_chars] & 0x40) && - tab_chars < 23) { - // In the middle of a multibyte UTF-8 character. - title[tab_chars] = label[tab_chars]; - tab_chars++; - } + if (label_len > tab_chars) snprintf(title + tab_chars, 4, "..."); + // Avoid unnecessary redraws + if (strcmp(this->label(), title)) { + this->copy_label(title); + this->redraw_label(); } - this->copy_label(title); - this->redraw_label(); // Disabled because of a bug in fltk::Tabgroup //dFree(TabTooltip); |