diff options
-rw-r--r-- | dpi/downloads.cc | 146 | ||||
-rw-r--r-- | src/dialog.cc | 55 | ||||
-rw-r--r-- | src/dialog.hh | 2 | ||||
-rw-r--r-- | src/nav.c | 6 | ||||
-rw-r--r-- | src/ui.cc | 379 | ||||
-rw-r--r-- | src/ui.hh | 101 | ||||
-rw-r--r-- | src/uicmd.cc | 618 |
7 files changed, 598 insertions, 709 deletions
diff --git a/dpi/downloads.cc b/dpi/downloads.cc index ab1b4f06..7466afd7 100644 --- a/dpi/downloads.cc +++ b/dpi/downloads.cc @@ -342,72 +342,72 @@ DLItem::DLItem(const char *full_filename, const char *url, DLAction action) gw = 400, gh = 70; group = new Fl_Group(0,0,gw,gh); group->begin(); - prTitle = new Fl_Box(24, 7, 290, 23, shortname); - prTitle->box(FL_RSHADOW_BOX); - prTitle->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP); - //prTitle->clear_flag (SHORTCUT_LABEL); - // Attach this 'log_text' to the tooltip - log_text_add("Target File: ", 13); - log_text_add(fullname, strlen(fullname)); - log_text_add("\n\n", 2); - - prBar = new ProgressBar(24, 40, 92, 20); - prBar->box(FL_BORDER_BOX); // ENGRAVED_BOX - prBar->tooltip("Progress Status"); - - int ix = 122, iy = 36, iw = 50, ih = 14; - Fl_Widget *o = new Fl_Box(ix,iy,iw,ih, "Got"); - o->box(FL_RFLAT_BOX); - o->color((Fl_Color)0xc0c0c000); - o->tooltip("Downloaded Size"); - prGot = new Fl_Box(ix,iy+14,iw,ih, "0KB"); - prGot->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); - prGot->labelcolor((Fl_Color)0x6c6cbd00); - prGot->box(FL_NO_BOX); - - ix += iw; - o = new Fl_Box(ix,iy,iw,ih, "Size"); - o->box(FL_RFLAT_BOX); - o->color((Fl_Color)0xc0c0c000); - o->tooltip("Total Size"); - prSize = new Fl_Box(ix,iy+14,iw,ih, "??"); - prSize->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); - prSize->box(FL_NO_BOX); - - ix += iw; - o = new Fl_Box(ix,iy,iw,ih, "Rate"); - o->box(FL_RFLAT_BOX); - o->color((Fl_Color)0xc0c0c000); - o->tooltip("Current transfer Rate (KBytes/sec)"); - prRate = new Fl_Box(ix,iy+14,iw,ih, "??"); - prRate->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); - prRate->box(FL_NO_BOX); - - ix += iw; - o = new Fl_Box(ix,iy,iw,ih, "~Rate"); - o->box(FL_RFLAT_BOX); - o->color((Fl_Color)0xc0c0c000); - o->tooltip("Average transfer Rate (KBytes/sec)"); - pr_Rate = new Fl_Box(ix,iy+14,iw,ih, "??"); - pr_Rate->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); - pr_Rate->box(FL_NO_BOX); - - ix += iw; - prETAt = o = new Fl_Box(ix,iy,iw,ih, "ETA"); - o->box(FL_RFLAT_BOX); - o->color((Fl_Color)0xc0c0c000); - o->tooltip("Estimated Time of Arrival"); - prETA = new Fl_Box(ix,iy+14,iw,ih, "??"); - prETA->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); - prETA->box(FL_NO_BOX); - - //ix += 50; - //prButton = new Fl_Button(ix, 41, 38, 19, "Stop"); - prButton = new Fl_Button(328, 9, 38, 19, "Stop"); - prButton->tooltip("Stop this transfer"); - prButton->box(FL_UP_BOX); - prButton->clear_visible_focus(); - prButton->callback(prButton_scb, this); + prTitle = new Fl_Box(24, 7, 290, 23, shortname); + prTitle->box(FL_RSHADOW_BOX); + prTitle->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP); + //prTitle->clear_flag (SHORTCUT_LABEL); + // Attach this 'log_text' to the tooltip + log_text_add("Target File: ", 13); + log_text_add(fullname, strlen(fullname)); + log_text_add("\n\n", 2); + + prBar = new ProgressBar(24, 40, 92, 20); + prBar->box(FL_BORDER_BOX); // ENGRAVED_BOX + prBar->tooltip("Progress Status"); + + int ix = 122, iy = 36, iw = 50, ih = 14; + Fl_Widget *o = new Fl_Box(ix,iy,iw,ih, "Got"); + o->box(FL_RFLAT_BOX); + o->color((Fl_Color)0xc0c0c000); + o->tooltip("Downloaded Size"); + prGot = new Fl_Box(ix,iy+14,iw,ih, "0KB"); + prGot->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + prGot->labelcolor((Fl_Color)0x6c6cbd00); + prGot->box(FL_NO_BOX); + + ix += iw; + o = new Fl_Box(ix,iy,iw,ih, "Size"); + o->box(FL_RFLAT_BOX); + o->color((Fl_Color)0xc0c0c000); + o->tooltip("Total Size"); + prSize = new Fl_Box(ix,iy+14,iw,ih, "??"); + prSize->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + prSize->box(FL_NO_BOX); + + ix += iw; + o = new Fl_Box(ix,iy,iw,ih, "Rate"); + o->box(FL_RFLAT_BOX); + o->color((Fl_Color)0xc0c0c000); + o->tooltip("Current transfer Rate (KBytes/sec)"); + prRate = new Fl_Box(ix,iy+14,iw,ih, "??"); + prRate->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + prRate->box(FL_NO_BOX); + + ix += iw; + o = new Fl_Box(ix,iy,iw,ih, "~Rate"); + o->box(FL_RFLAT_BOX); + o->color((Fl_Color)0xc0c0c000); + o->tooltip("Average transfer Rate (KBytes/sec)"); + pr_Rate = new Fl_Box(ix,iy+14,iw,ih, "??"); + pr_Rate->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + pr_Rate->box(FL_NO_BOX); + + ix += iw; + prETAt = o = new Fl_Box(ix,iy,iw,ih, "ETA"); + o->box(FL_RFLAT_BOX); + o->color((Fl_Color)0xc0c0c000); + o->tooltip("Estimated Time of Arrival"); + prETA = new Fl_Box(ix,iy+14,iw,ih, "??"); + prETA->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + prETA->box(FL_NO_BOX); + + //ix += 50; + //prButton = new Fl_Button(ix, 41, 38, 19, "Stop"); + prButton = new Fl_Button(328, 9, 38, 19, "Stop"); + prButton->tooltip("Stop this transfer"); + prButton->box(FL_UP_BOX); + prButton->clear_visible_focus(); + prButton->callback(prButton_scb, this); group->box(FL_ROUND_UP_BOX); group->end(); @@ -1071,13 +1071,13 @@ DLWin::DLWin(int ww, int wh) { // Create the empty main window mWin = new Fl_Window(ww, wh, "Downloads:"); mWin->begin(); - mScroll = new Fl_Scroll(0,0,ww,wh); - mScroll->begin(); - mPG = new Fl_Pack(0,0,ww,wh); - mPG->end(); - //mPG->spacing(10); - mScroll->end(); - mScroll->type(Fl_Scroll::VERTICAL); + mScroll = new Fl_Scroll(0,0,ww,wh); + mScroll->begin(); + mPG = new Fl_Pack(0,0,ww,wh); + mPG->end(); + //mPG->spacing(10); + mScroll->end(); + mScroll->type(Fl_Scroll::VERTICAL); mWin->end(); mWin->resizable(mScroll); mWin->callback(dlwin_esc_cb, NULL); diff --git a/src/dialog.cc b/src/dialog.cc index a2b34fa9..c932118e 100644 --- a/src/dialog.cc +++ b/src/dialog.cc @@ -37,17 +37,6 @@ void a_Dialog_msg(const char *msg) } /* - * Offer a three choice dialog. - * - * Return: 0, 1 or 2 (esc = 0, window close = 0, enter = 1) - */ -int a_Dialog_choice3(const char *msg, - const char *b0, const char *b1, const char *b2) -{ - return fl_choice(msg, b0, b1, b2); -} - -/* * Dialog for one line of Input with a message. */ const char *a_Dialog_input(const char *msg) @@ -160,35 +149,33 @@ PORT1.3 /*--------------------------------------------------------------------------*/ static int choice5_answer; -#if 0 -PORT1.3 static void choice5_cb(Fl_Widget *button, void *number) { choice5_answer = VOIDP2INT(number); _MSG("choice5_cb: %d\n", choice5_answer); - button->window()->make_exec_return(true); + button->window()->hide(); } -#endif /* - * Make a question-dialog with a question and some alternatives. + * Make a question-dialog with a question and up to five alternatives. + * (if less alternatives, non used parameters must be NULL). + * * Return value: 0 = dialog was cancelled, 1-5 = selected alternative. */ int a_Dialog_choice5(const char *QuestionTxt, const char *alt1, const char *alt2, const char *alt3, const char *alt4, const char *alt5) { -#if 0 -PORT1.3 choice5_answer = 0; - int ww = 440, wh = 150, bw = 50, bh = 45, nb = 0; + int ww = 440, wh = 120, bw = 50, bh = 45, ih = 50, nb = 0; const char *txt[7]; txt[0] = txt[6] = NULL; txt[1] = alt1; txt[2] = alt2; txt[3] = alt3; txt[4] = alt4; txt[5] = alt5; - for (int i=1; txt[i]; ++i, ++nb) ; + for (int i=1; txt[i]; ++i, ++nb); + ww = 140 + nb*(bw+10); Fl_Window *window = new Fl_Window(ww,wh,"Choice5"); window->begin(); @@ -196,10 +183,20 @@ PORT1.3 ib->begin(); window->resizable(ib); - Fl_Box *box = new Fl_Box(0,0,ww,wh-bh, QuestionTxt); - box->box(FL_DOWN_BOX); - box->labelfont(FL_HELVETICA_BOLD_ITALIC); + /* '?' Icon */ + Fl_Box* o = new Fl_Box(10, (wh-bh-ih)/2, ih, ih); + o->box(FL_THIN_UP_BOX); + o->labelfont(FL_TIMES_BOLD); + o->labelsize(34); + o->color(FL_WHITE); + o->labelcolor(FL_BLUE); + o->label("?"); + o->show(); + + Fl_Box *box = new Fl_Box(60,0,ww-60,wh-bh, QuestionTxt); + box->labelfont(FL_HELVETICA); box->labelsize(14); + box->align(FL_ALIGN_WRAP); Fl_Button *b; int xpos = 0, gap = 8; @@ -211,18 +208,16 @@ PORT1.3 b->box(FL_UP_BOX); b->callback(choice5_cb, INT2VOIDP(i)); xpos += bw + gap; + /* TODO: set focus to the *-prefixed alternative */ } window->end(); - //window->hotspot(box); - window->exec(); - delete window; - _MSG("Choice5 answer = %d\n", choice5_answer); + window->show(); + while (window->shown()) + Fl::wait(); + _MSG("a_Dialog_choice5 answer = %d\n", choice5_answer); return choice5_answer; -#else -return 1 + fl_choice(QuestionTxt, alt1, alt2, alt3); -#endif } diff --git a/src/dialog.hh b/src/dialog.hh index 440e9bba..57b21849 100644 --- a/src/dialog.hh +++ b/src/dialog.hh @@ -9,8 +9,6 @@ typedef void (*UserPasswordCB)(const char *user, const char *password, void *vp); void a_Dialog_msg(const char *msg); -int a_Dialog_choice3(const char *msg, - const char *b0, const char *b1, const char *b2); int a_Dialog_choice5(const char *QuestionTxt, const char *alt1, const char *alt2, const char *alt3, const char *alt4, const char *alt5); @@ -488,9 +488,9 @@ static void Nav_reload_callback(void *data) confirmed = 0; } else if (URL_FLAGS(h_url) & URL_Post) { /* Attempt to repost data, let's confirm... */ - choice = a_Dialog_choice3("Repost form data?", - "No", "Yes", "Cancel"); - confirmed = (choice == 1); /* "Yes" */ + choice = a_Dialog_choice5("Repost form data?", + "No", "Yes", "Cancel", NULL, NULL); + confirmed = (choice == 2); /* "Yes" */ } if (confirmed) { @@ -103,12 +103,14 @@ int CustInput::handle(int e) _MSG("CustInput::handle event=%d\n", e); // We're only interested in some flags - unsigned modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT); + //unsigned modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT); // Don't focus with arrow keys if (e == FL_FOCUS && (k == FL_Up || k == FL_Down || k == FL_Left || k == FL_Right)) { return 0; + } +#if 0 } else if (e == FL_KEYBOARD) { if (modifier == FL_CTRL) { if (k == 'l') { @@ -126,7 +128,7 @@ int CustInput::handle(int e) } } _MSG("\n"); - +#endif return Fl_Input::handle(e); } @@ -173,8 +175,8 @@ public: padding = w > 2 ? w/2 : 1; } copy_label(lbl); - measure_label(w,h); - size(w+padding,h); + //measure_label(w,h); + //size(w+padding,this->h()); redraw_label(); } }; @@ -380,58 +382,40 @@ static void bugmeter_cb(Fl_Widget *wid, void *data) //---------------------------- /* - * Create the archetipic browser buttons + * Make a generic navigation button */ -Fl_Pack *UI::make_toolbar(int tw, int th) +Fl_Button *UI::make_button(const char *label, Fl_Image *img, Fl_Image *deimg, + int b_n, int start) { - Fl_Button *b; - Fl_Pack *p1=new Fl_Pack(0,0,tw,th); - p1->begin(); - Back = b = new Fl_Button(xpos, 0, bw, bh, (lbl) ? "Back" : 0); - b->image(icons->ImgLeft); - b->deimage(icons->ImgLeftIn); - b->callback(b1_cb, (void *)UI_BACK); - b->clear_visible_focus(); - - Forw = b = new Fl_Button(xpos, 0, bw, bh, (lbl) ? "Forw" : 0); - b->image(icons->ImgRight); - b->deimage(icons->ImgRightIn); - b->callback(b1_cb, (void *)UI_FORW); - b->clear_visible_focus(); - - Home = b = new Fl_Button(xpos, 0, bw, bh, (lbl) ? "Home" : 0); - b->image(icons->ImgHome); - b->callback(b1_cb, (void *)UI_HOME); - b->clear_visible_focus(); - - Reload = b = new Fl_Button(xpos, 0, bw, bh, (lbl) ? "Reload" : 0); - b->image(icons->ImgReload); - b->callback(b1_cb, (void *)UI_RELOAD); - b->clear_visible_focus(); - - Save = b = new Fl_Button(xpos, 0, bw, bh, (lbl) ? "Save" : 0); - b->image(icons->ImgSave); - b->callback(b1_cb, (void *)UI_SAVE); - b->clear_visible_focus(); - - Stop = b = new Fl_Button(xpos, 0, bw, bh, (lbl) ? "Stop" : 0); - b->image(icons->ImgStop); - b->deimage(icons->ImgStopIn); - b->callback(b1_cb, (void *)UI_STOP); - b->clear_visible_focus(); - - Bookmarks = b = new Fl_Button(xpos, 0, bw, bh, (lbl) ? "Book" : 0); - b->image(icons->ImgBook); - b->callback(b1_cb, (void *)UI_BOOK); - b->clear_visible_focus(); - - Tools = b = new Fl_Button(xpos, 0, bw, bh, (lbl) ? "Tools" : 0); - b->image(icons->ImgTools); - b->callback(b1_cb, (void *)UI_TOOLS); - b->clear_visible_focus(); + if (start) + p_xpos = 0; + + Fl_Button *b = new Fl_Button(p_xpos, 0, bw, bh, (lbl) ? label : NULL); + if (img) + b->image(img); + if (deimg) + b->deimage(deimg); + b->callback(b1_cb, (void *)b_n); + b->clear_visible_focus(); + b->labelsize(12); + b->box(FL_NO_BOX); + p_xpos += bw; + return b; +} - p1->type(Fl_Pack::HORIZONTAL); - p1->end(); +/* + * Create the archetipic browser buttons + */ +void UI::make_toolbar(int tw, int th) +{ + Back = make_button("Back", icons->ImgLeft, icons->ImgLeftIn, UI_BACK, 1); + Forw = make_button("Forw", icons->ImgRight, icons->ImgRightIn, UI_FORW); + Home = make_button("Home", icons->ImgHome, NULL, UI_HOME); + Reload = make_button("Reload", icons->ImgReload, NULL, UI_RELOAD); + Save = make_button("Save", icons->ImgSave, NULL, UI_SAVE); + Stop = make_button("Stop", icons->ImgStop, icons->ImgStopIn, UI_STOP); + Bookmarks = make_button("Book", icons->ImgBook, NULL, UI_BOOK); + Tools = make_button("Tools", icons->ImgTools, NULL, UI_TOOLS); if (prefs.show_tooltip) { Back->tooltip("Previous page"); @@ -443,40 +427,41 @@ Fl_Pack *UI::make_toolbar(int tw, int th) Bookmarks->tooltip("View bookmarks"); Tools->tooltip("Settings"); } - return p1; } /* * Create the location box (Clear/Input/Search) */ -Fl_Pack *UI::make_location() +void UI::make_location(int ww) { Fl_Button *b; - Fl_Pack *pg = new Fl_Pack(0,0,0,0); - pg->begin(); - Clear = b = new CustButton(2,2,16,22,0); + + Clear = b = new CustButton(p_xpos,0,16,lh,0); b->image(icons->ImgClear); b->callback(clear_cb, this); b->clear_visible_focus(); + b->box(FL_THIN_UP_BOX); + p_xpos += b->w(); - Fl_Input *i = Location = new CustInput(0,0,0,0,0); + Fl_Input *i = Location = new CustInput(p_xpos,0,ww-p_xpos-32,lh,0); i->color(CuteColor); i->when(FL_WHEN_ENTER_KEY); i->callback(location_cb, this); + p_xpos += i->w(); - Search = b = new Fl_Button(0,0,16,22,0); + Search = b = new Fl_Button(p_xpos,0,16,lh,0); b->image(icons->ImgSearch); b->callback(search_cb, this); b->clear_visible_focus(); + b->box(FL_THIN_UP_BOX); + p_xpos += b->w(); - Help = b = new Fl_Button(0,0,16,22,0); + Help = b = new Fl_Button(p_xpos,0,16,lh,0); b->image(icons->ImgHelp); b->callback(help_cb, this); b->clear_visible_focus(); - - pg->type(Fl_Pack::HORIZONTAL); - pg->resizable(i); - pg->end(); + b->box(FL_THIN_UP_BOX); + p_xpos += b->w(); if (prefs.show_tooltip) { Clear->tooltip("Clear the URL box.\nMiddle-click to paste a URL."); @@ -484,30 +469,26 @@ Fl_Pack *UI::make_location() Search->tooltip("Search the Web"); Help->tooltip("Help"); } - return pg; } /* * Create the progress bars */ -Fl_Pack *UI::make_progress_bars(int wide, int thin_up) +void UI::make_progress_bars(int wide, int thin_up) { - ProgBox = new Fl_Pack(0,0,0,0); - ProgBox->begin(); // Images - IProg = new CustProgressBox(0,0,0,0); + IProg = new CustProgressBox(p_xpos,p_ypos,pw,bh); + IProg->labelsize(12); IProg->box(thin_up ? FL_THIN_UP_BOX : FL_EMBOSSED_BOX); IProg->labelcolor(FL_GRAY_RAMP + 2); IProg->update_label(wide ? "Images\n0 of 0" : "0 of 0"); + p_xpos += pw; // Page - PProg = new CustProgressBox(0,0,0,0); + PProg = new CustProgressBox(p_xpos,p_ypos,pw,bh); + PProg->labelsize(12); PProg->box(thin_up ? FL_THIN_UP_BOX : FL_EMBOSSED_BOX); PProg->labelcolor(FL_GRAY_RAMP + 2); PProg->update_label(wide ? "Page\n0.0KB" : "0.0KB"); - ProgBox->type(Fl_Pack::HORIZONTAL); - ProgBox->end(); - - return ProgBox; } /* @@ -519,14 +500,15 @@ Fl_Widget *UI::make_filemenu_button() Fl_Button *btn; int w,h, padding; - FileButton = btn = new Fl_Button(0,0,0,0,"W"); + FileButton = btn = new Fl_Button(p_xpos,0,0,0,"W"); btn->measure_label(w, h); padding = w; btn->copy_label(PanelSize == P_tiny ? "&F" : "&File"); btn->measure_label(w,h); if (PanelSize == P_large) h = fh; - btn->size(w+padding,h); + btn->size(w+padding,PanelSize == P_tiny ? bh : lh); + p_xpos += btn->w(); _MSG("UI::make_filemenu_button w=%d h=%d padding=%d\n", w, h, padding); btn->box(PanelSize == P_large ? FL_FLAT_BOX : FL_THIN_UP_BOX); btn->callback(filemenu_cb, this); @@ -542,11 +524,9 @@ Fl_Widget *UI::make_filemenu_button() /* * Create the control panel */ -Fl_Group *UI::make_panel(int ww) +void UI::make_panel(int ww) { Fl_Widget *w; - Fl_Group *g1, *g2, *g3; - Fl_Pack *pg; if (PanelSize > P_large) { PanelSize = P_tiny; @@ -558,105 +538,91 @@ Fl_Group *UI::make_panel(int ww) else icons = &standard_icons; + pw = 70; + p_xpos = p_ypos = 0; if (PanelSize == P_tiny) { if (Small_Icons) - xpos = 0, bw = 22, bh = 22, fh = 0, lh = 22, lbl = 0; + bw = 22, bh = 22, fh = 0, lh = 22, lbl = 0; else - xpos = 0, bw = 28, bh = 28, fh = 0, lh = 28, lbl = 0; + bw = 28, bh = 28, fh = 0, lh = 28, lbl = 0; } else if (PanelSize == P_small) { if (Small_Icons) - xpos = 0, bw = 20, bh = 20, fh = 0, lh = 20, lbl = 0; + bw = 20, bh = 20, fh = 0, lh = 20, lbl = 0; else - xpos = 0, bw = 28, bh = 28, fh = 0, lh = 28, lbl = 0; + bw = 28, bh = 28, fh = 0, lh = 28, lbl = 0; } else if (PanelSize == P_medium) { if (Small_Icons) - xpos = 0, bw = 42, bh = 36, fh = 0, lh = 22, lbl = 1; + bw = 42, bh = 36, fh = 0, lh = 22, lbl = 1; else - xpos = 0, bw = 45, bh = 45, fh = 0, lh = 28, lbl = 1; + bw = 45, bh = 45, fh = 0, lh = 28, lbl = 1; } else { // P_large if (Small_Icons) - xpos = 0, bw = 42, bh = 36, fh = 22, lh = 22, lbl = 1; + bw = 42, bh = 36, fh = 22, lh = 22, lbl = 1; else - xpos = 0, bw = 45, bh = 45, fh = 24, lh = 28, lbl = 1; + bw = 45, bh = 45, fh = 24, lh = 28, lbl = 1; } + nh = bh, sh = 24; if (PanelSize == P_tiny) { - g1 = new Fl_Group(0,0,ww,bh); - // Toolbar - pg = make_toolbar(ww,bh); - pg->box(FL_EMBOSSED_BOX); - g1->add(pg); - w = make_filemenu_button(); - pg->add(w); - w = make_location(); - pg->add(w); - pg->resizable(w); - w = make_progress_bars(0,1); - pg->add(w); - - g1->resizable(pg); - + NavBar = new CustGroup(0,0,ww,bh); + NavBar->begin(); + make_toolbar(ww,bh); + make_filemenu_button(); + make_location(ww); + NavBar->resizable(Location); + make_progress_bars(0,1); + NavBar->box(FL_THIN_UP_FRAME); + NavBar->end(); } else { - g1 = new Fl_Group(0,0,ww,fh+lh+bh); - g1->begin(); - // File menu - if (PanelSize == P_large) { - g3 = new Fl_Group(0,0,ww,lh); + // File menu + if (PanelSize == P_large) { + Fl_Group *g3 = new Fl_Group(0,0,ww,lh); + g3->begin(); g3->box(FL_FLAT_BOX); Fl_Widget *bn = make_filemenu_button(); - g3->add(bn); g3->add_resizable(*new Fl_Box(bn->w(),0,ww - bn->w(),lh)); - - g2 = new Fl_Group(0,fh,ww,lh); - g2->begin(); - pg = make_location(); - pg->size(ww,lh); - } else { - g2 = new Fl_Pack(0,fh,ww,lh); - g2->type(Fl_Pack::HORIZONTAL); - g2->begin(); + g3->end(); + + LocBar = new CustGroup(0,0,ww,lh); + LocBar->begin(); + make_location(ww); + LocBar->end(); + } else { + LocBar = new CustGroup(0,0,ww,lh); + p_xpos = 0; make_filemenu_button(); - pg = make_location(); - } - - g2->resizable(pg); - g2->end(); + make_location(ww); + LocBar->resizable(Location); + LocBar->end(); + } // Toolbar - g3 = new Fl_Group(0,fh+lh,ww,bh); - g3->begin(); - pg = make_toolbar(ww,bh); - //w = new Fl_Box(0,0,0,0,"i n v i s i b l e"); - w = new Fl_Box(0,0,0,0,0); - pg->add(w); - pg->resizable(w); - + p_ypos = 0; + NavBar = new CustGroup(0,0,ww,bh); + NavBar->begin(); + make_toolbar(ww,bh); + w = new Fl_Box(p_xpos,0,ww-p_xpos-2*pw,bh); + w->box(FL_NO_BOX); + NavBar->resizable(w); + p_xpos = ww - 2*pw; if (PanelSize == P_small) { - w = make_progress_bars(0,0); + make_progress_bars(0,0); } else { - w = make_progress_bars(1,0); + make_progress_bars(1,0); } - pg->add(w); - - g3->resizable(pg); // Better than 'w3' and it also works - pg->box(FL_BORDER_FRAME); - //g3->box(FL_EMBOSSED_BOX); - g3->end(); - - g1->resizable(g3); - g1->end(); + NavBar->end(); } - - return g1; } /* * Create the status panel */ -Fl_Group *UI::make_status_panel(int ww) +void UI::make_status_panel(int ww) { const int s_h = 20, bm_w = 16; - Fl_Group *g = new Fl_Group(0, 0, ww, s_h, 0); + // HACK: we need a defined StatusOutput + StatusPanel = new Fl_Group(0, 400, 1, 1, 0); + StatusPanel->end(); // Status box StatusOutput = new Fl_Output(0, 0, ww-bm_w, s_h, 0); @@ -664,7 +630,6 @@ Fl_Group *UI::make_status_panel(int ww) StatusOutput->box(FL_THIN_DOWN_BOX); StatusOutput->clear_visible_focus(); StatusOutput->color(FL_GRAY_RAMP + 18); - g->add(StatusOutput); //StatusOutput->throw_focus(); // Bug Meter @@ -676,25 +641,21 @@ Fl_Group *UI::make_status_panel(int ww) BugMeter->tooltip("Show HTML bugs\n(right-click for menu)"); BugMeter->callback(bugmeter_cb, this); BugMeter->clear_visible_focus(); - g->add(BugMeter); - - g->resizable(StatusOutput); - return g; } /* * User Interface constructor */ -UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) : - Fl_Group(x, y, ww, wh, label) +UI::UI(int x, int y, int ui_w, int ui_h, const char* label, const UI *cur_ui) : + Fl_Pack(x, y, ui_w, ui_h, label) { PointerOnLink = FALSE; Tabs = NULL; TabTooltip = NULL; - TopGroup = new Fl_Pack(0, 0, ww, wh); - add(TopGroup); - resizable(TopGroup); + TopGroup = this; + TopGroup->type(VERTICAL); + //resizable(TopGroup); clear_flag(SHORTCUT_LABEL); if (cur_ui) { @@ -716,28 +677,31 @@ UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) : } // Control panel - Panel = make_panel(ww); - TopGroup->add(Panel); - - // Render area - Main = new Fl_Group(0,0,1,1,"Welcome..."); - Main->box(FL_FLAT_BOX); - Main->color(FL_GRAY_RAMP + 3); - Main->labelfont(FL_HELVETICA_BOLD_ITALIC); - Main->labelsize(36); - Main->labeltype(FL_SHADOW_LABEL); - Main->labelcolor(FL_WHITE); - TopGroup->add(Main); - TopGroup->resizable(Main); - MainIdx = TopGroup->find(Main); - - // Find text bar - findbar = new Findbar(ww, 28); - TopGroup->add(findbar); - - // Status Panel - StatusPanel = make_status_panel(ww); - TopGroup->add(StatusPanel); + TopGroup->begin(); + make_panel(ui_w); + + // Render area + int mh = ui_h - (lh+bh+sh); + Main = new Fl_Group(0,0,0,mh,"Welcome..."); + Main->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + Main->box(FL_FLAT_BOX); + Main->color(FL_GRAY_RAMP + 3); + Main->labelfont(FL_HELVETICA_BOLD_ITALIC); + Main->labelsize(36); + Main->labeltype(FL_SHADOW_LABEL); + Main->labelcolor(FL_WHITE); + TopGroup->resizable(Main); + MainIdx = TopGroup->find(Main); + + // Find text bar + findbar = new Findbar(ui_w, 28); + //TopGroup->add(findbar); + + // Status Panel + make_status_panel(ui_w); + //TopGroup->add(StatusPanel); + + TopGroup->end(); // Make the full screen button (to be attached to the viewport later) // TODO: attach to the viewport @@ -749,7 +713,7 @@ UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) : customize(0); if (Panelmode) { - Panel->hide(); + //Panel->hide(); StatusPanel->hide(); } } @@ -772,7 +736,7 @@ int UI::handle(int event) _MSG("Panel->h()=%d Main->h()=%d\n", Panel->h() , Main->h()); int ret = 0; - +#if 0 if (event == FL_KEYBOARD) { return 0; // Receive as shortcut } else if (event == FL_SHORTCUT) { @@ -857,7 +821,7 @@ int UI::handle(int event) } } } - +#endif if (!ret) { ret = Fl_Group::handle(event); } @@ -1019,8 +983,10 @@ void UI::customize(int flags) Search->hide(); if ( !prefs.show_help ) Help->hide(); - if ( !prefs.show_progress_box ) - ProgBox->hide(); +// if ( !prefs.show_progress_box ) +// ProgBox->hide(); + + NavBar->rearrange(); } /* @@ -1028,6 +994,7 @@ void UI::customize(int flags) */ void UI::panel_cb_i() { +#if 0 Fl_Group *NewPanel; // Create a new Panel @@ -1038,7 +1005,7 @@ void UI::panel_cb_i() TopGroup->add(NewPanel); Panel = NewPanel; customize(0); - +#endif Location->take_focus(); } @@ -1063,11 +1030,11 @@ void UI::color_change_cb_i() void UI::set_panelmode(UIPanelmode mode) { if (mode == UI_HIDDEN) { - Panel->hide(); + //Panel->hide(); StatusPanel->hide(); } else { /* UI_NORMAL or UI_TEMPORARILY_SHOW_PANELS */ - Panel->show(); + //Panel->show(); StatusPanel->show(); } Panelmode = mode; @@ -1094,49 +1061,13 @@ void UI::panelmode_cb_i() */ void UI::set_render_layout(Fl_Group &nw) { - // BUG: replace() is not working as it should. - // In our case, replacing the rendering area leaves the vertical - // scrollbar without events. - // - // We'll use a workaround in a_UIcmd_browser_window_new() instead. TopGroup->remove(MainIdx); delete(Main); - TopGroup->add(nw); + TopGroup->insert(nw, MainIdx); Main = &nw; + TopGroup->resizable(Main); //TopGroup->box(FL_DOWN_BOX); //TopGroup->box(FL_BORDER_FRAME); - TopGroup->resizable(TopGroup->child(MainIdx)); -} - -/* - * Set the tab title - */ -void UI::set_tab_title(const char *label) -{ - char title[128]; - - dReturn_if_fail(label != NULL); - - if (*label) { - // Make a label for this tab - size_t tab_chars = 18, label_len = strlen(label); - - 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 (label_len > tab_chars) - snprintf(title + tab_chars, 4, "..."); - // Avoid unnecessary redraws - if (strcmp(this->label(), title)) { - this->copy_label(title); - this->redraw_label(); - } - - // Disabled because of a bug in fltk::Tabgroup - //dFree(TabTooltip); - //TabTooltip = dStrdup(label); - //this->tooltip(TabTooltip); - } } /* @@ -35,18 +35,93 @@ typedef enum { // Private classes class CustProgressBox; -class CustTabGroup; +class CustTabs; + + +// Class definition ---------------------------------------------------------- +/* + * Used to reposition group's widgets when some of them are hidden + */ +class CustGroup : public Fl_Group { +public: + CustGroup(int x,int y,int w ,int h,const char *l = 0) : + Fl_Group(x,y,w,h,l) { }; + void rearrange(void) { + int n = children(), xpos = 0, r_x1, r_i = -1, i; + + init_sizes(); + for (i = 0; i < n; ++i) { + if (child(i) == resizable()) { + r_i = i; + r_x1 = xpos; + break; + } + if (child(i)->visible()) { + child(i)->position(xpos, child(i)->y()); + xpos += child(i)->w(); + } + } + if (r_i < 0) + return; + xpos = w(); + for (i = n - 1; i > r_i; --i) { + if (child(i)->visible()) { + xpos -= child(i)->w(); + child(i)->position(xpos, child(i)->y()); + } + } + child(r_i)->resize(r_x1, child(r_i)->y(), xpos-r_x1, child(r_i)->h()); + redraw(); + } + void rearrange_y(void) { + int n = children(), pos = 0, r_pos, r_i = -1, i; + + printf("children = %d\n", n); + init_sizes(); + for (i = 0; i < n; ++i) { + if (child(i) == resizable()) { + r_i = i; + r_pos = pos; + break; + } + if (child(i)->visible()) { + printf("child[%d] x=%d y=%d w=%d h=%d\n", + i, child(i)->x(), pos, child(i)->w(), child(i)->h()); + child(i)->position(child(i)->x(), pos); + pos += child(i)->h(); + } + } + if (r_i < 0) + return; + pos = h(); + for (i = n - 1; i > r_i; --i) { + if (child(i)->visible()) { + pos -= child(i)->h(); + printf("child[%d] x=%d y=%d w=%d h=%d\n", + i, child(i)->x(), pos, child(i)->w(), child(i)->h()); + child(i)->position(child(i)->x(), pos); + } + } + child(r_i)->resize(child(r_i)->x(), r_pos, child(r_i)->w(), pos-r_pos); + printf("resizable child[%d] x=%d y=%d w=%d h=%d\n", + r_i, child(r_i)->x(), r_pos, child(r_i)->w(), child(r_i)->h()); + child(r_i)->hide(); + redraw(); + } +}; + // // UI class definition ------------------------------------------------------- // -class UI : public Fl_Group { - CustTabGroup *Tabs; +class UI : public Fl_Pack { + CustTabs *Tabs; char *TabTooltip; Fl_Group *TopGroup; Fl_Button *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks, *Tools, *Clear, *Search, *Help, *FullScreen, *BugMeter, *FileButton; + CustGroup *LocBar, *NavBar, *StBar; Fl_Input *Location; Fl_Pack *ProgBox; CustProgressBox *PProg, *IProg; @@ -56,19 +131,20 @@ class UI : public Fl_Group { int MainIdx; // Panel customization variables int PanelSize, CuteColor, Small_Icons; - int xpos, bw, bh, fh, lh, lbl; + int p_xpos, p_ypos, bw, bh, fh, lh, nh, sh, pw, lbl; UIPanelmode Panelmode; Findbar *findbar; int PointerOnLink; - - Fl_Pack *make_toolbar(int tw, int th); - Fl_Pack *make_location(); - Fl_Pack *make_progress_bars(int wide, int thin_up); + Fl_Button *make_button(const char *label, Fl_Image *img, + Fl_Image*deimg, int b_n, int start = 0); + void make_toolbar(int tw, int th); + void make_location(int ww); + void make_progress_bars(int wide, int thin_up); void make_menubar(int x, int y, int w, int h); Fl_Widget *make_filemenu_button(); - Fl_Group *make_panel(int ww); - Fl_Group *make_status_panel(int ww); + void make_panel(int ww); + void make_status_panel(int ww); public: @@ -87,7 +163,6 @@ public: void set_img_prog(int n_img, int t_img, int cmd); void set_bug_prog(int n_bug); void set_render_layout(Fl_Group &nw); - void set_tab_title(const char *label); void customize(int flags); void button_set_sens(UIButton btn, int sens); void paste_url(); @@ -97,8 +172,8 @@ public: Fl_Widget *fullscreen_button() { return FullScreen; } void fullscreen_toggle() { FullScreen->do_callback(); } - CustTabGroup *tabs() { return Tabs; } - void tabs(CustTabGroup *tabs) { Tabs = tabs; } + CustTabs *tabs() { return Tabs; } + void tabs(CustTabs *tabs) { Tabs = tabs; } int pointerOnLink() { return PointerOnLink; } void pointerOnLink(int flag) { PointerOnLink = flag; } diff --git a/src/uicmd.cc b/src/uicmd.cc index ab053dfb..7a8c3ccd 100644 --- a/src/uicmd.cc +++ b/src/uicmd.cc @@ -16,10 +16,12 @@ #include <stdarg.h> #include <math.h> /* for rint */ +#include <FL/Fl.H> #include <FL/Fl_Widget.H> #include <FL/Fl_Double_Window.H> -#include <FL/Fl_Tabs.H> -#include <FL/Fl_Tooltip.H> +#include <FL/Fl_Wizard.H> +#include <FL/Fl_Box.H> +#include <FL/names.h> #include "paths.hh" #include "keys.hh" @@ -54,332 +56,277 @@ using namespace dw::fltk; * Local data */ static char *save_dir = NULL; +static UI *Gui; +/* + * Forward declarations + */ +static BrowserWindow *UIcmd_tab_new(CustTabs *tabs, int focus); //---------------------------------------------------------------------------- -#if 0 -#define BTN_W 25 -#define BTN_H 20 - -static int btn_x; +/* + * CustTabs --------------------------------------------------------------- + */ /* - * Adds a tab-close button at the rightmost part + * stores the respective UI pointer */ -class CustShrinkTabPager : public TabGroupPager { - bool btn_hl; - TabGroup *tg; +class CustTabButton : public Fl_Button { + UI *ui_; public: - int update_positions( - TabGroup *g, int numchildren, int &selected, - int &cumulated_width, int &available_width, - int *tab_pos, int *tab_width); - virtual int which(TabGroup* g, int m_x,int m_y); - virtual TabGroupPager* clone() const; - virtual const char * mode_name() const {return "Shrink";} - virtual int id() const {return PAGER_SHRINK;} - virtual int available_width(TabGroup *g) const; - virtual bool draw_tabs(TabGroup* g, int selected, int* tab_pos, - int* tab_width) { - if (!tg) tg = g; - if (g->children() > 1) { - fltk::Rectangle r(btn_x,0,BTN_W,BTN_H); - setcolor(btn_hl ? 206 : GRAY75); - fillrect(r); - if (btn_hl) { - setcolor(FL_WHITE); - strokerect(r); - } - setcolor(GRAY10); - //fltk::setfont(fltk::getfont()->bold(), fltk::getsize()); - r.h(r.h()-2); - drawtext("X", r, ALIGN_CENTER); - return false; - } else { - // WORKAROUND: for http://fltk.org/str.php?L2062 - // By returning true we avoid a call to TabGroup::draw_tab() - // in TabGroup::draw() in case we don't show the tabs. - return true; - } - } + CustTabButton (int x,int y,int w,int h, const char* label = 0) : + Fl_Button (x,y,w,h,label) { ui_ = NULL; }; + void ui(UI *pui) { ui_ = pui; } + UI *ui(void) { return ui_; } +}; - void btn_highlight(bool flag) { - if (btn_hl != flag) { - btn_hl = flag; - if (tg) - tg->redraw(DAMAGE_VALUE); - } +/* + * Allows fine control of the tabbed interface + */ +class CustTabs : public CustGroup { + int tab_w, tab_h, tab_n; + Fl_Wizard *Wizard; + int tabcolor_inactive, tabcolor_active, curtab_idx; +public: + CustTabs (int ww, int wh, int th, const char *lbl=0) : + CustGroup(0,0,ww,th,lbl) { + tab_w = 80, tab_h = th, tab_n = 0, curtab_idx = -1; + tabcolor_active = FL_DARK_CYAN; tabcolor_inactive = 206; + Fl_Box *w = new Fl_Box(0,0,0,0,"i n v i s i b l e"); + w->box(FL_NO_BOX); + resizable(0); + end(); + + Wizard = new Fl_Wizard(0,tab_h,ww,wh-tab_h); + Wizard->end(); }; - bool btn_highlight() { return btn_hl; }; - - CustShrinkTabPager() : TabGroupPager() { - noclip(true); - btn_hl = false; - tg = NULL; - } + int handle(int e); + UI *add_new_tab(int focus); + void remove_tab(UI *ui); + Fl_Wizard *wizard(void) { return Wizard; } + int get_btn_idx(UI *ui); + int num_tabs() { return (children() - 1); } // substract invisible box + void switch_tab(CustTabButton *cbtn); + void prev_tab(void); + void next_tab(void); + + void set_tab_label(UI *ui, const char *title); }; -int CustShrinkTabPager::available_width(TabGroup *g) const +/* + * Callback for mouse click + */ +static void tab_btn_cb (Fl_Widget *w, void *cb_data) { - _MSG("CustShrinkTabPager::available_width\n"); - int w = MAX (g->w() - this->slope()-1 - BTN_W, 0); - btn_x = w + 6; - return w; + CustTabButton *btn = (CustTabButton*) w; + CustTabs *tabs = (CustTabs*) cb_data; + int b = Fl::event_button(); + + if (b == FL_LEFT_MOUSE) { + tabs->switch_tab(btn); + } else if (b == FL_RIGHT_MOUSE) { + // TODO: just an example, not necessarily final + a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(btn->ui())); + } } -int CustShrinkTabPager::which(TabGroup* g, int event_x,int event_y) +int CustTabs::handle(int e) { - int H = g->tab_height(); - if (!H) return -1; - if (H < 0) { - if (event_y > g->h() || event_y < g->h()+H) return -1; - } else { - if (event_y > H || event_y < 0) return -1; - } - if (event_x < 0) return -1; - int p[128], w[128]; - int selected = g->tab_positions(p, w); - int d = (event_y-(H>=0?0:g->h()))*slope()/H; - for (int i=0; i<g->children(); i++) { - if (event_x < p[i+1]+(i<selected ? slope() - d : d)) return i; + int ret = 0; + + _MSG("CustTabs::handle e=%s\n", fl_eventnames[e]); + if (e == FL_KEYBOARD) { + return 0; // Receive as shortcut + } else if (e == FL_SHORTCUT) { + UI *ui = (UI*)wizard()->value(); + BrowserWindow *bw = a_UIcmd_get_bw_by_widget(ui); + KeysCommand_t cmd = Keys::getKeyCmd(); + if (cmd == KEYS_NOP) { + // Do nothing + } else if (cmd == KEYS_NEW_TAB) { + a_UIcmd_open_url_nt(bw, NULL, 1); + ret = 1; + } else if (cmd == KEYS_CLOSE_TAB) { + a_UIcmd_close_bw(bw); + ret = 1; + } else if (cmd == KEYS_LEFT_TAB) { + MSG("CustTabs::handle KEYS_LEFT_TAB\n"); + ret = 1; + } else if (cmd == KEYS_RIGHT_TAB) { + MSG("CustTabs::handle KEYS_RIGHT_TAB\n"); + ret = 1; + } else if (cmd == KEYS_NEW_WINDOW) { + a_UIcmd_browser_window_new(ui->w(),ui->h()+this->h(),0,bw); + ret = 1; + } else if (cmd == KEYS_FULLSCREEN) { + MSG("CustTabs::handle KEYS_FULLSCREEN\n"); + ret = 1; + } else if (cmd == KEYS_CLOSE_ALL) { + a_Timeout_add(0.0, a_UIcmd_close_all_bw, NULL); + ret = 1; + } + + } else if (e == FL_KEYUP) { + int k = Fl::event_key(); + // We're only interested in some flags + unsigned modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT); + if (k == FL_Up || k == FL_Down || k == FL_Tab) { + ; + } else if (k == FL_Left || k == FL_Right) { + if (modifier == FL_SHIFT) { + (k == FL_Left) ? prev_tab() : next_tab(); + ret = 1; + } + } } - return -1; + + return (ret) ? ret : CustGroup::handle(e); } /* - * Prevents tabs from going over the close-tab button. - * Modified from fltk-2.0.x-r6525. + * Create a new tab with its own UI */ -int CustShrinkTabPager::update_positions( - TabGroup *g, int numchildren, int &selected, - int &cumulated_width, int &available_width, - int *tab_pos, int *tab_width) +UI *CustTabs::add_new_tab(int focus) { - available_width-=BTN_W; + char tab_label[64]; - // uh oh, they are too big, we must move them: - // special case when the selected tab itself is too big, make it fill - // cumulated_width: - int i; + current(0); + UI *new_ui = new UI(0,tab_h,Wizard->w(),Wizard->h()); + new_ui->tabs(this); + Wizard->add(new_ui); + new_ui->show(); - if (tab_width[selected] >= available_width) { - tab_width[selected] = available_width; - for (i = 0; i <= selected; i++) - tab_pos[i] = 0; - for (i = selected + 1; i <= numchildren; i++) - tab_pos[i] = available_width; - return selected; - } + snprintf(tab_label, 64,"ctab%d", ++tab_n); + CustTabButton *btn = new CustTabButton(num_tabs()*tab_w,0,tab_w,tab_h); + btn->align(FL_ALIGN_INSIDE|FL_ALIGN_CLIP); + btn->copy_label(tab_label); + btn->clear_visible_focus(); + btn->box(FL_PLASTIC_ROUND_UP_BOX); + btn->color(tabcolor_active); + btn->ui(new_ui); + add(btn); + btn->redraw(); + btn->callback(tab_btn_cb, this); - int w2[128]; + if (focus) + switch_tab(btn); + rearrange(); - for (i = 0; i < numchildren; i++) - w2[i] = tab_width[i]; - i = numchildren - 1; - int j = 0; + return new_ui; +} - int minsize = 5; +/* + * Remove tab by UI + */ +void CustTabs::remove_tab(UI *ui) +{ + CustTabButton *btn; - bool right = true; + // remove label button + int idx = get_btn_idx(ui); + btn = (CustTabButton*)child(idx); + idx > 1 ? prev_tab() : next_tab(); + remove(idx); + delete btn; + rearrange(); + //TODO: redraw doesn't work sometimes + redraw(); - while (cumulated_width > available_width) { - int n; // which one to shrink + Wizard->remove(ui); + delete(ui); - if (j < selected && (!right || i <= selected)) { // shrink a left one - n = j++; - right = true; - } else if (i > selected) { // shrink a right one - n = i--; - right = false; - } else { // no more space, start making them zero - minsize = 0; - i = numchildren - 1; - j = 0; - right = true; - continue; - } - cumulated_width -= w2[n] - minsize; - w2[n] = minsize; - if (cumulated_width < available_width) { - w2[n] = available_width - cumulated_width + minsize; - cumulated_width = available_width; - break; - } + if (num_tabs() == 0) { + window()->hide(); + // TODO: free memory + //delete window(); } - // re-sum the positions: - cumulated_width = 0; - for (i = 0; i < numchildren; i++) { - cumulated_width += w2[i]; - tab_pos[i+1] = cumulated_width; +} + +int CustTabs::get_btn_idx(UI *ui) +{ + for (int i = 1; i <= num_tabs(); ++i) { + CustTabButton *btn = (CustTabButton*)child(i); + if (btn->ui() == ui) + return i; } - return selected; + return -1; } -TabGroupPager* CustShrinkTabPager::clone() const { - return new CustShrinkTabPager(*this); +void CustTabs::switch_tab(CustTabButton *cbtn) +{ + int idx; + CustTabButton *btn; + UI *old_ui = (UI*)Wizard->value(); + + if (cbtn->ui() != old_ui) { + // Set old tab label to normal color + if ((idx = get_btn_idx(old_ui)) > 0) { + btn = (CustTabButton*)child(idx); + btn->color(tabcolor_inactive); + btn->redraw(); + } + Wizard->value(cbtn->ui()); + cbtn->color(tabcolor_active); + cbtn->redraw(); + } } -#endif /* custom pager */ -//---------------------------------------------------------------------------- -/* - * For custom handling of keyboard - */ -class CustTabGroup : public Fl_Tabs { - Fl_Tooltip *toolTip; - bool tooltipEnabled; - bool buttonPushed; -public: - CustTabGroup (int x, int y, int ww, int wh, const char *lbl=0) : - Fl_Tabs(x,y,ww,wh,lbl) { - Fl_Group::current(0); - box(FL_NO_BOX); - // The parameter pager is cloned, so free it. -// CustShrinkTabPager *cp = new CustShrinkTabPager(); -// this->pager(cp); -// delete cp; - toolTip = new Fl_Tooltip; - tooltipEnabled = false; - buttonPushed = false; - }; - ~CustTabGroup() { delete toolTip; } - int handle(int e) { - // Don't focus with arrow keys - _MSG("CustTabGroup::handle %d\n", e); -// fltk::Rectangle r(btn_x,0,BTN_W,BTN_H); - if (e == FL_KEYBOARD) { - int k = Fl::event_key(); - // We're only interested in some flags - unsigned modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT); - if (k == FL_Up || k == FL_Down || k == FL_Tab) { - return 0; - } else if (k == FL_Left || k == FL_Right) { - if (modifier == FL_SHIFT) { - int i = find(value()); - if (k == FL_Left) {i = i ? i-1 : children()-1;} - else {i++; if (i >= children()) i = 0;} - value(child(i)); - return 1; - } - // Avoid focus change. - return 0; - } - } else if (e == FL_RELEASE) { - Fl_Widget *new_focus = which(Fl::event_x(), Fl::event_y()); +void CustTabs::prev_tab() +{ + int idx; - if (new_focus && new_focus != value()) { - // Update the window title - BrowserWindow *bw = a_UIcmd_get_bw_by_widget(new_focus); - const char *title = a_History_get_title(NAV_TOP_UIDX(bw), 1); + if ((idx = get_btn_idx((UI*)Wizard->value())) > 1) + switch_tab( (CustTabButton*)child(idx-1) ); +} - value(new_focus); - a_UIcmd_set_page_title(bw, title ? title : ""); - } -// custom pager -#if 0 - } else if (e == FL_MOVE) { - CustShrinkTabPager *cstp = (CustShrinkTabPager *) pager(); - if (Fl::event_inside(r) && children() > 1) { - /* We're inside the button area */ - cstp->btn_highlight(true); - if (prefs.show_tooltip) { - /* Prepare the tooltip for pop-up */ - tooltipEnabled = true; - /* We use parent() if available because we are returning 0. - * Returning without having TabGroup processing makes the - * popup event never reach 'this', but it reaches parent() */ - toolTip->enter(parent() ?parent():this, r, "Close current Tab"); - } - return 0; // Change focus - } else { - cstp->btn_highlight(false); - - if (prefs.show_tooltip) { - /* Hide the tooltip or enable it again.*/ - if (tooltipEnabled) { - tooltipEnabled = false; - toolTip->exit(); - } else { - toolTip->enable(); - } - } - } - } else if (e == FL_PUSH && Fl::event_inside(r) && - Fl::event_button() == 1 && children() > 1) { - buttonPushed = true; - return 1; /* non-zero */ - } else if (e == FL_RELEASE) { - if (Fl::event_inside(r) && Fl::event_button() == 1 && - children() > 1 && buttonPushed) { - a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(value())); - } else { - CustShrinkTabPager *cstp = (CustShrinkTabPager *) pager(); - cstp->btn_highlight(false); - } - buttonPushed = false; -#endif - } else if (e == FL_DRAG) { - /* Ignore this event */ - return 1; - } - int ret = Fl_Tabs::handle(e); +void CustTabs::next_tab() +{ + int idx; - if (e == FL_PUSH) { - /* WORKAROUND: FLTK raises the window on unhandled clicks, - * which we do not want. - */ - ret = 1; - } - return ret; - } + if ((idx = get_btn_idx((UI*)Wizard->value())) > 0 && idx < num_tabs()) + switch_tab( (CustTabButton*)child(idx+1) ); +} - void remove (Fl_Widget *w) { - Fl_Tabs::remove (w); - /* fixup resizable in case we just removed it */ - if (resizable () == w) { - if (children () > 0) - resizable (child (children () - 1)); - else - resizable (NULL); - } +/* + * Set this UI's tab button label + */ +void CustTabs::set_tab_label(UI *ui, const char *label) +{ + char title[128]; + int idx = get_btn_idx(ui); + + if (idx > 0) { + // Make a label for this tab + size_t tab_chars = 7, label_len = strlen(label); - if (children () < 2) { - box(FL_NO_BOX); - hideLabels (); - } - } + 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 (label_len > tab_chars) + snprintf(title + tab_chars, 4, "..."); - void add (Fl_Widget *w) { - Fl_Tabs::add (w); - if (children () > 1) { - box(FL_THIN_UP_BOX); - showLabels (); + // Avoid unnecessary redraws + if (strcmp(child(idx)->label(), title)) { + child(idx)->copy_label(title); + child(idx)->redraw_label(); } } +} - void hideLabels() { - for (int i = children () - 1; i >= 0; i--) - child(i)->resize(x(), y(), w(), h()); - } - - void showLabels() { - for (int i = children () - 1; i >= 0; i--) - child(i)->resize(x(), y() + 20, w(), h() - 20); - } -}; //---------------------------------------------------------------------------- static void win_cb (Fl_Widget *w, void *cb_data) { - int choice = 0; - CustTabGroup *tabs = (CustTabGroup*) cb_data; + int choice = 1; + CustTabs *tabs = (CustTabs*) cb_data; - if (tabs->children () > 1) - choice = a_Dialog_choice3 ("Window contains more than one tab.", - "Cancel", "Close all tabs", NULL); + if (tabs->num_tabs() > 1) + choice = a_Dialog_choice5("Window contains more than one tab.", + "Close all tabs", "Cancel", NULL, NULL, NULL); if (choice == 1) - while (tabs->children()) - a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(tabs->child(0))); + while (tabs->num_tabs()) + a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(tabs->wizard()->value())); } /* @@ -390,8 +337,9 @@ BrowserWindow *a_UIcmd_get_bw_by_widget(void *v_wid) BrowserWindow *bw; for (int i = 0; i < a_Bw_num(); ++i) { bw = a_Bw_get(i); - if (((Fl_Widget*)bw->ui)->contains((Fl_Widget*)v_wid)) + if (((UI*)bw->ui)->contains((Fl_Widget*)v_wid)) { return bw; + } } return NULL; } @@ -434,88 +382,37 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, else win = new Fl_Double_Window(ww, wh); - Fl_Group::current(0); -//may need a handler for this -// win->shortcut(0); // Ignore Escape - CustTabGroup *DilloTabs = new CustTabGroup(0, 0, ww, wh); - DilloTabs->selection_color(156); - win->add(DilloTabs); - - // Create and set the UI - UI *new_ui = new UI(0, 0, ww, wh, DEFAULT_TAB_LABEL, - old_bw ? BW2UI(old_bw) : NULL); - new_ui->set_status("http://www.dillo.org/"); - new_ui->tabs(DilloTabs); + //Fl_Group::current(0); + CustTabs *DilloTabs = new CustTabs(ww, wh, 16); + win->end(); - DilloTabs->add(new_ui); - DilloTabs->resizable(new_ui); - DilloTabs->window()->resizable(new_ui); - DilloTabs->window()->show(); + new_bw = UIcmd_tab_new(DilloTabs, 1); + win->resizable(Gui); + win->show(); if (old_bw == NULL && prefs.xpos >= 0 && prefs.ypos >= 0) { // position the first window according to preferences - new_ui->window()->position(prefs.xpos, prefs.ypos); + DilloTabs->window()->position(prefs.xpos, prefs.ypos); } - // Now create the Dw render layout and viewport - FltkPlatform *platform = new FltkPlatform (); - Layout *layout = new Layout (platform); - style::Color *bgColor = style::Color::create (layout, prefs.bg_color); - layout->setBgColor (bgColor); - - FltkViewport *viewport = new FltkViewport (0, 0, 1, 1); - if (prefs.buffered_drawing == 1) - viewport->setBufferedDrawing (true); - else - viewport->setBufferedDrawing (false); - - layout->attachView (viewport); - new_ui->set_render_layout(*viewport); - - viewport->setScrollStep((int) rint(14.0 * prefs.font_factor)); - - // Now, create a new browser window structure - new_bw = a_Bw_new(); - - // Reference the UI from the bw - new_bw->ui = (void *)new_ui; - // Copy the layout pointer into the bw data - new_bw->render_layout = (void*)layout; - win->callback(win_cb, DilloTabs); - new_ui->focus_location(); + //new_ui->focus_location(); return new_bw; } /* - * Create a new Tab. - * i.e the new UI and its associated BrowserWindow data structure. + * Create a new Tab button, UI and its associated BrowserWindow data + * structure. */ -static BrowserWindow *UIcmd_tab_new(const void *vbw) +static BrowserWindow *UIcmd_tab_new(CustTabs *tabs, int focus) { - _MSG(" UIcmd_tab_new vbw=%p\n", vbw); - - dReturn_val_if_fail (vbw != NULL, NULL); - - BrowserWindow *new_bw = NULL; - BrowserWindow *old_bw = (BrowserWindow*)vbw; - UI *ui = BW2UI(old_bw); - - // WORKAROUND: limit the number of tabs because of a fltk bug - if (ui->tabs()->children() >= 127) - return a_UIcmd_browser_window_new(ui->window()->w(), ui->window()->h(), - 0, vbw); + MSG(" UIcmd_tab_new\n"); // Create and set the UI - UI *new_ui = new UI(0, 0, ui->w(), ui->h(), DEFAULT_TAB_LABEL, ui); - new_ui->tabs(ui->tabs()); - - new_ui->tabs()->add(new_ui); - new_ui->tabs()->resizable(new_ui); - new_ui->tabs()->window()->resizable(new_ui); - new_ui->tabs()->window()->show(); + UI *new_ui = tabs->add_new_tab(1); + Gui = new_ui; // Now create the Dw render layout and viewport FltkPlatform *platform = new FltkPlatform (); @@ -524,14 +421,13 @@ static BrowserWindow *UIcmd_tab_new(const void *vbw) layout->setBgColor (bgColor); FltkViewport *viewport = new FltkViewport (0, 0, 1, 1); - + viewport->setBufferedDrawing (prefs.buffered_drawing ? true : false); layout->attachView (viewport); new_ui->set_render_layout(*viewport); - viewport->setScrollStep((int) rint(14.0 * prefs.font_factor)); // Now, create a new browser window structure - new_bw = a_Bw_new(); + BrowserWindow *new_bw = a_Bw_new(); // Reference the UI from the bw new_bw->ui = (void *)new_ui; @@ -552,16 +448,11 @@ void a_UIcmd_close_bw(void *vbw) MSG("a_UIcmd_close_bw\n"); a_Bw_stop_clients(bw, BW_Root + BW_Img + BW_Force); + //TODO: sometimes this call segfaults upon exit + delete(layout); if (ui->tabs()) { - ui->tabs()->remove(ui); - if (ui->tabs()->value()) - ui->tabs()->value()->take_focus(); - else - ui->tabs()->window()->hide(); + ui->tabs()->remove_tab(ui); } - delete(layout); - delete(ui); - a_Bw_free(bw); } @@ -571,11 +462,11 @@ void a_UIcmd_close_bw(void *vbw) void a_UIcmd_close_all_bw(void *) { BrowserWindow *bw; - int choice = 0; + int choice = 1; if (a_Bw_num() > 1) - choice = a_Dialog_choice3 ("More than one open tab or window.", - "Cancel", "Close all tabs and windows", NULL); + choice = a_Dialog_choice5("More than one open tab or Window.", + "Close all tabs and windows", "Cancel", NULL, NULL, NULL); if (choice == 1) while ((bw = a_Bw_get(0))) a_UIcmd_close_bw((void*)bw); @@ -627,9 +518,11 @@ void a_UIcmd_open_urlstr(void *vbw, const char *urlstr) void a_UIcmd_open_url(BrowserWindow *bw, const DilloUrl *url) { a_Nav_push(bw, url, NULL); +#if 0 if (BW2UI(bw)->get_panelmode() == UI_TEMPORARILY_SHOW_PANELS) BW2UI(bw)->set_panelmode(UI_HIDDEN); a_UIcmd_focus_main_area(bw); +#endif } static void UIcmd_open_url_nbw(BrowserWindow *new_bw, const DilloUrl *url) @@ -664,11 +557,8 @@ void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url) */ void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus) { - BrowserWindow *new_bw = UIcmd_tab_new(vbw); - - if (focus) - BW2UI(new_bw)->tabs()->value(BW2UI(new_bw)); - + BrowserWindow *bw = (BrowserWindow *)vbw; + BrowserWindow *new_bw = UIcmd_tab_new(BW2UI(bw)->tabs(), focus); UIcmd_open_url_nbw(new_bw, url); } @@ -1235,7 +1125,7 @@ void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label) const int size = 128; char title[size]; - if (a_UIcmd_get_bw_by_widget(BW2UI(bw)->tabs()->value()) == bw) { + if (a_UIcmd_get_bw_by_widget(BW2UI(bw)->tabs()->wizard()->value()) == bw) { // This is the focused bw, set window title if (snprintf(title, size, "Dillo: %s", label) >= size) { uint_t i = MIN(size - 4, 1 + a_Utf8_end_of_char(title, size - 8)); @@ -1244,7 +1134,7 @@ void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label) BW2UI(bw)->window()->copy_label(title); BW2UI(bw)->window()->redraw_label(); } - BW2UI(bw)->set_tab_title(label); + BW2UI(bw)->tabs()->set_tab_label(BW2UI(bw), label); } /* |