aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjcid <devnull@localhost>2008-09-18 00:16:38 +0200
committerjcid <devnull@localhost>2008-09-18 00:16:38 +0200
commitf9da96dd24c8f8c83a88d0ed77d562aa456a33c4 (patch)
tree6a950a2728516159bde5d3d0da5c932cbbb21542 /src
parentd61666920e33d15d25ac6381e4f4c64f66165493 (diff)
- Implemented tabbed browsing.
Diffstat (limited to 'src')
-rw-r--r--src/findbar.cc21
-rw-r--r--src/findbar.hh6
-rw-r--r--src/menu.cc10
-rw-r--r--src/nav.c2
-rw-r--r--src/pixmaps.h8
-rw-r--r--src/ui.cc226
-rw-r--r--src/ui.hh20
-rw-r--r--src/uicmd.cc120
-rw-r--r--src/uicmd.hh4
9 files changed, 252 insertions, 165 deletions
diff --git a/src/findbar.cc b/src/findbar.cc
index 0807a4fa..ba4d24ad 100644
--- a/src/findbar.cc
+++ b/src/findbar.cc
@@ -10,13 +10,13 @@
*/
#include <fltk/events.h>
+#include <fltk/Window.h>
#include "findbar.hh"
#include "msg.h"
#include "pixmaps.h"
#include "uicmd.hh"
#include "bw.h"
-#include "ui.hh"
/*
* Local sub class
@@ -31,12 +31,12 @@ public:
int MyInput::handle(int e)
{
- _MSG("findbar NewInput::handle()\n");
+ _MSG("findbar MyInput::handle()\n");
int ret = 1, k = event_key();
unsigned modifier = event_state() & (SHIFT | CTRL | ALT | META);
if (modifier == 0) {
if (e == KEY && k == EscapeKey) {
- _MSG("findbar NewInput: caught EscapeKey\n");
+ _MSG("findbar CustInput: caught EscapeKey\n");
ret = 0;
}
}
@@ -55,7 +55,7 @@ void Findbar::search_cb(Widget *, void *vfb)
bool case_sens = fb->cb->value();
if (key[0] != '\0')
- a_UIcmd_findtext_search((BrowserWindow *) fb->ui->user_data(),
+ a_UIcmd_findtext_search((BrowserWindow *) fb->window()->user_data(),
key, case_sens);
}
@@ -83,7 +83,7 @@ void Findbar::hide_cb(Widget *, void *vfb)
/*
* Construct text search bar
*/
-Findbar::Findbar(int width, int height, UI *ui) :
+Findbar::Findbar(int width, int height) :
Group(0, 0, width, height)
{
int button_width = 70;
@@ -93,8 +93,8 @@ Findbar::Findbar(int width, int height, UI *ui) :
int x = border;
height -= 2 * border;
- this->ui = ui;
- this->hide();
+ box(PLASTIC_UP_BOX);
+ Group::hide();
begin();
hidebutton = new HighlightButton(x, border, 16, height, 0);
@@ -113,7 +113,7 @@ Findbar::Findbar(int width, int height, UI *ui) :
i->callback(search_cb2, this);
// todo: search previous would be nice
- findb = new HighlightButton(x, border, button_width, height, "&Next");
+ findb = new HighlightButton(x, border, button_width, height, "Next");
x += button_width + gap;
findb->tooltip("Find next occurrence of the search phrase");
findb->add_shortcut(ReturnKey);
@@ -140,7 +140,7 @@ int Findbar::handle(int event)
int k = event_key();
unsigned modifier = event_state() & (SHIFT | CTRL | ALT | META);
- if (modifier == 0 && k == EscapeKey) {
+ if (event == KEY && modifier == 0 && k == EscapeKey) {
hide();
ret = 1;
}
@@ -170,6 +170,7 @@ void Findbar::hide()
BrowserWindow *bw;
Group::hide();
- if ((bw = (BrowserWindow *) ui->user_data()))
+ if ((bw = (BrowserWindow *) this->window()->user_data()))
a_UIcmd_findtext_reset(bw);
+ a_UIcmd_focus_main_area(bw);
}
diff --git a/src/findbar.hh b/src/findbar.hh
index db803140..b5591889 100644
--- a/src/findbar.hh
+++ b/src/findbar.hh
@@ -9,9 +9,6 @@
#include <fltk/Group.h>
#include <fltk/CheckButton.h>
-// simple declaration to avoid circular include
-class UI;
-
using namespace fltk;
/*
@@ -22,7 +19,6 @@ class Findbar : public Group {
Button *clrb;
HighlightButton *hidebutton;
xpmImage *hideImg;
- UI *ui;
Input *i;
CheckButton *cb;
@@ -31,7 +27,7 @@ class Findbar : public Group {
static void hide_cb (Widget *, void *);
public:
- Findbar(int width, int height, UI *ui);
+ Findbar(int width, int height);
~Findbar();
int handle(int event);
void show();
diff --git a/src/menu.cc b/src/menu.cc
index 111e6182..c6a4bb90 100644
--- a/src/menu.cc
+++ b/src/menu.cc
@@ -49,10 +49,10 @@ static int *history_list = NULL;
* Used to add the hint for history popup menus, and to remember
* the mouse button pressed over a menu item.
*/
-class NewItem : public Item {
+class CustItem : public Item {
int EventButton;
public:
- NewItem (const char* label) : Item(label) { EventButton = 0; };
+ CustItem (const char* label) : Item(label) { EventButton = 0; };
int button () { return EventButton; };
void draw();
int handle(int e) {
@@ -65,7 +65,7 @@ public:
* This adds a call to a_UIcmd_set_msg() to show the URL in the status bar
* TODO: erase the URL on popup close.
*/
-void NewItem::draw() {
+void CustItem::draw() {
DilloUrl *url;
if (flags() & SELECTED) {
@@ -217,7 +217,7 @@ static void Menu_bugmeter_about_cb(Widget* )
*/
static void Menu_history_cb(Widget *wid, void *data)
{
- int mb = ((NewItem*)wid)->button();
+ int mb = ((CustItem*)wid)->button();
int offset = history_direction * VOIDP2INT(data);
if (mb == 2) {
@@ -438,7 +438,7 @@ void a_Menu_history_popup(BrowserWindow *bw, int direction)
pm->begin();
for (i = 0; history_list[i] != -1; i += 1) {
// TODO: restrict title size
- it = new NewItem(a_History_get_title(history_list[i], 1));
+ it = new CustItem(a_History_get_title(history_list[i], 1));
it->callback(Menu_history_cb, (void*)(i+1));
}
pm->type(PopupMenu::POPUP123);
diff --git a/src/nav.c b/src/nav.c
index bbc6942a..872303a8 100644
--- a/src/nav.c
+++ b/src/nav.c
@@ -396,7 +396,7 @@ void a_Nav_push_nw(BrowserWindow *bw, const DilloUrl *url)
BrowserWindow *newbw;
a_UIcmd_get_wh(bw, &w, &h);
- newbw = a_UIcmd_browser_window_new(w, h, bw->ui);
+ newbw = a_UIcmd_browser_window_new(w, h, bw);
a_Nav_push(newbw, url);
}
diff --git a/src/pixmaps.h b/src/pixmaps.h
index 43d2268b..3043ead4 100644
--- a/src/pixmaps.h
+++ b/src/pixmaps.h
@@ -1497,8 +1497,8 @@ static const char *const mini_ok_xpm[] = {
/* XPM */
static const char *const imgload_on_xpm[] = {
"15 15 2 1",
-" c #FFFFFFFFFFFF",
-". c #00000000CF3C",
+" c None",
+". c #00000000CF3C",
" ",
" . . . ... ",
" . .. .. . . ",
@@ -1518,8 +1518,8 @@ static const char *const imgload_on_xpm[] = {
/* XPM */
static const char *const imgload_off_xpm[] = {
"15 15 2 1",
-" c #FFFFFFFFFFFF",
-". c #CF3C00000000",
+" c None",
+". c #CF3C00000000",
" ",
" . . . ... ",
" . .. .. . . ",
diff --git a/src/ui.cc b/src/ui.cc
index 042b58aa..927c18a2 100644
--- a/src/ui.cc
+++ b/src/ui.cc
@@ -39,9 +39,9 @@ using namespace fltk;
* (Used to avoid certain shortcuts in the location bar)
*/
-class NewInput : public Input {
+class CustInput : public Input {
public:
- NewInput (int x, int y, int w, int h, const char* l=0) :
+ CustInput (int x, int y, int w, int h, const char* l=0) :
Input(x,y,w,h,l) {};
int handle(int e);
};
@@ -50,25 +50,31 @@ public:
* Disable: UpKey, DownKey, PageUpKey, PageDownKey and
* CTRL+{o,r,HomeKey,EndKey}
*/
-int NewInput::handle(int e)
+int CustInput::handle(int e)
{
int k = event_key();
- _MSG("NewInput::handle event=%d\n", e);
+ _MSG("CustInput::handle event=%d\n", e);
+
+ // We're only interested in some flags
+ unsigned modifier = event_state() & (SHIFT | CTRL | ALT);
// Don't focus with arrow keys
if (e == FOCUS &&
- (k == UpKey || k == DownKey || k == LeftKey|| k == RightKey)) {
+ (k == UpKey || k == DownKey || k == LeftKey || k == RightKey)) {
return 0;
- }
-
- if (event_state(CTRL)) {
- if (e == KEY && k == 'l') {
- // Make text selected when already focused.
- position(size(), 0);
- return 0;
- } else if (k == 'o' || k == 'r' || k == HomeKey || k == EndKey)
- return 0;
+ } else if (e == KEY) {
+ if (modifier == CTRL) {
+ if (k == 'l') {
+ // Make text selected when already focused.
+ position(size(), 0);
+ return 1;
+ } else if (k == 'o')
+ return 0;
+ } else if (modifier == SHIFT) {
+ if (k == LeftKey || k == RightKey)
+ return 0;
+ }
}
_MSG("\n");
@@ -80,14 +86,14 @@ int NewInput::handle(int e)
/*
* Used to handle "paste" within the toolbar's Clear button.
*/
-class NewHighlightButton : public HighlightButton {
+class CustHighlightButton : public HighlightButton {
public:
- NewHighlightButton(int x, int y, int w, int h, const char *l=0) :
+ CustHighlightButton(int x, int y, int w, int h, const char *l=0) :
HighlightButton(x,y,w,h,l) {};
int handle(int e);
};
-int NewHighlightButton::handle(int e)
+int CustHighlightButton::handle(int e)
{
if (e == PASTE) {
const char* t = event_text();
@@ -105,9 +111,9 @@ int NewHighlightButton::handle(int e)
/*
* Used to resize the progress boxes automatically.
*/
-class NewProgressBox : public InvisibleBox {
+class CustProgressBox : public InvisibleBox {
public:
- NewProgressBox(int x, int y, int w, int h, const char *l=0) :
+ CustProgressBox(int x, int y, int w, int h, const char *l=0) :
InvisibleBox(x,y,w,h,l) {};
void update_label(const char *lbl) {
static int padding = 0;
@@ -138,14 +144,6 @@ public:
//
/*
- * Callback handler for the close window event.
- */
-static void close_window_cb(Widget *wid, void *data)
-{
- a_UIcmd_close_bw(data);
-}
-
-/*
* Callback for the search button.
*/
static void search_cb(Widget *wid, void *data)
@@ -197,7 +195,7 @@ static void color_change_cb(Widget *wid, void *data)
static void location_cb(Widget *wid, void *data)
{
Input *i = (Input*)wid;
- UI *ui = (UI*)i->window();
+ UI *ui = (UI*)data;
/* This test is necessary because WHEN_ENTER_KEY also includes
* other events we're not interested in. For instance pressing
@@ -281,15 +279,15 @@ static void b1_cb(Widget *wid, void *cb_data)
/*
* Callback for the bug meter button.
*/
-static void bugmeter_cb(Widget *w, void *data)
+static void bugmeter_cb(Widget *wid, void *data)
{
int k = event_key();
if (k && k <= 7)
MSG("[BugMeter], mouse button %d was pressed\n", k);
if (k == 1) {
- a_UIcmd_view_page_bugs(((UI*)data)->user_data());
+ a_UIcmd_view_page_bugs(wid->window()->user_data());
} else if (k == 3) {
- a_UIcmd_bugmeter_popup(((UI*)data)->user_data());
+ a_UIcmd_bugmeter_popup(wid->window()->user_data());
}
}
@@ -415,14 +413,14 @@ PackedGroup *UI::make_location()
Button *b;
PackedGroup *pg = new PackedGroup(0,0,0,0);
pg->begin();
- Clear = b = new NewHighlightButton(2,2,16,22,0);
+ Clear = b = new CustHighlightButton(2,2,16,22,0);
ImgClear = new xpmImage(new_s_xpm);
b->image(ImgClear);
b->tooltip("Clear the URL box.\nMiddle-click to paste a URL.");
- b->callback(clear_cb, (void *)this);
+ b->callback(clear_cb, this);
b->clear_tab_to_focus();
- Input *i = Location = new NewInput(0,0,0,0,0);
+ Input *i = Location = new CustInput(0,0,0,0,0);
i->tooltip("Location");
i->color(CuteColor);
i->when(WHEN_ENTER_KEY);
@@ -433,7 +431,7 @@ PackedGroup *UI::make_location()
ImgSearch = new xpmImage(search_xpm);
b->image(ImgSearch);
b->tooltip("Search the Web");
- b->callback(search_cb, (void *)this);
+ b->callback(search_cb, this);
b->clear_tab_to_focus();
pg->type(PackedGroup::ALL_CHILDREN_VERTICAL);
@@ -451,12 +449,12 @@ PackedGroup *UI::make_progress_bars(int wide, int thin_up)
ProgBox = new PackedGroup(0,0,0,0);
ProgBox->begin();
// Images
- IProg = new NewProgressBox(0,0,0,0);
+ IProg = new CustProgressBox(0,0,0,0);
IProg->box(thin_up ? THIN_UP_BOX : EMBOSSED_BOX);
IProg->labelcolor(GRAY10);
IProg->update_label(wide ? "Images\n0 of 0" : "0 of 0");
// Page
- PProg = new NewProgressBox(0,0,0,0);
+ PProg = new CustProgressBox(0,0,0,0);
PProg->box(thin_up ? THIN_UP_BOX : EMBOSSED_BOX);
PProg->labelcolor(GRAY10);
PProg->update_label(wide ? "Page\n0.0KB" : "0.0KB");
@@ -471,19 +469,15 @@ PackedGroup *UI::make_progress_bars(int wide, int thin_up)
*/
static void menubar_cb(Widget *wid, void *data)
{
- UI *ui = (UI*)wid->window();
-
if (strcmp((char*)data, "nb") == 0) {
- a_UIcmd_browser_window_new(wid->window()->w(), wid->window()->h(), ui);
+ a_UIcmd_browser_window_new(wid->window()->w(), wid->window()->h(),
+ wid->window()->user_data());
} else if (strcmp((char*)data, "of") == 0) {
- a_UIcmd_open_file(ui->user_data());
+ a_UIcmd_open_file(wid->window()->user_data());
} else if (strcmp((char*)data, "ou") == 0) {
- if (ui->get_panelmode() == UI_HIDDEN) {
- ui->set_panelmode(UI_TEMPORARILY_SHOW_PANELS);
- }
- ui->focus_location();
+ a_UIcmd_focus_location(wid->window()->user_data());
} else if (strcmp((char*)data, "cw") == 0) {
- a_UIcmd_close_bw(ui->user_data());
+ a_UIcmd_close_bw(wid->window()->user_data());
} else if (strcmp((char*)data, "ed") == 0) {
a_UIcmd_close_all_bw();
}
@@ -608,13 +602,14 @@ Group *UI::make_panel(int ww)
/*
* User Interface constructor
*/
-UI::UI(int win_w, int win_h, const char* label, const UI *cur_ui) :
- Window(win_w, win_h, label)
+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;
- clear_double_buffer();
- TopGroup = new PackedGroup(0, 0, win_w, win_h);
+ Tabs = NULL;
+ TabTooltip = NULL;
+ TopGroup = new PackedGroup(0, 0, ww, wh);
add(TopGroup);
resizable(TopGroup);
@@ -633,12 +628,8 @@ UI::UI(int win_w, int win_h, const char* label, const UI *cur_ui) :
}
- // Set handler for the close window event
- // (the argument is set later via user_data())
- callback(close_window_cb);
-
// Control panel
- Panel = make_panel(win_w);
+ Panel = make_panel(ww);
TopGroup->add(Panel);
@@ -655,17 +646,16 @@ UI::UI(int win_w, int win_h, const char* label, const UI *cur_ui) :
MainIdx = TopGroup->find(Main);
// Find text bar
- findbar = new Findbar(win_w, 30, this);
+ findbar = new Findbar(ww, 28);
TopGroup->add(findbar);
// Status Panel
- StatusPanel = new Group(0, 0, win_w, s_h, 0);
+ StatusPanel = new Group(0, 0, ww, s_h, 0);
// Status box
int il_w = 16;
int bm_w = 16;
- Status = new Output(0, 0, win_w-bm_w-il_w, s_h, 0);
+ Status = new Output(0, 0, ww-bm_w-il_w, s_h, 0);
Status->value("");
- //Status->box(UP_BOX);
Status->box(THIN_DOWN_BOX);
Status->clear_click_to_focus();
Status->clear_tab_to_focus();
@@ -674,7 +664,7 @@ UI::UI(int win_w, int win_h, const char* label, const UI *cur_ui) :
//Status->throw_focus();
// Image loading indicator
- ImageLoad = new HighlightButton(win_w-il_w-bm_w,0,il_w,s_h,0);
+ ImageLoad = new HighlightButton(ww-il_w-bm_w,0,il_w,s_h,0);
ImgImageLoadOn = new xpmImage(imgload_on_xpm);
ImgImageLoadOff = new xpmImage(imgload_off_xpm);
if (prefs.load_images) {
@@ -685,19 +675,19 @@ UI::UI(int win_w, int win_h, const char* label, const UI *cur_ui) :
ImageLoad->box(THIN_DOWN_BOX);
ImageLoad->align(ALIGN_INSIDE|ALIGN_CLIP|ALIGN_LEFT);
ImageLoad->tooltip("Toggle image loading");
- ImageLoad->callback(imageload_cb, (void *)this);
+ ImageLoad->callback(imageload_cb, this);
ImageLoad->clear_tab_to_focus();
StatusPanel->add(ImageLoad);
// Bug Meter
- BugMeter = new HighlightButton(win_w-bm_w,0,bm_w,s_h,0);
+ BugMeter = new HighlightButton(ww-bm_w,0,bm_w,s_h,0);
ImgMeterOK = new xpmImage(mini_ok_xpm);
ImgMeterBug = new xpmImage(mini_bug_xpm);
BugMeter->image(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, (void *)this);
+ BugMeter->callback(bugmeter_cb, this);
BugMeter->clear_tab_to_focus();
StatusPanel->add(BugMeter);
@@ -712,7 +702,7 @@ UI::UI(int win_w, int win_h, const char* label, const UI *cur_ui) :
ImgFullScreenOff = new xpmImage(full_screen_off_xpm);
//FullScreen->image(ImgFullScreenOn);
//FullScreen->tooltip("Hide Controls");
- //FullScreen->callback(fullscreen_cb, (void *)this);
+ //FullScreen->callback(fullscreen_cb, this);
customize(0);
@@ -729,6 +719,8 @@ UI::UI(int win_w, int win_h, const char* label, const UI *cur_ui) :
*/
UI::~UI()
{
+ _MSG("UI::~UI()\n");
+ dFree(TabTooltip);
delete_panel_images();
delete_status_panel_images();
delete ImgFullScreenOn;
@@ -751,79 +743,75 @@ void UI::delete_status_panel_images()
*/
int UI::handle(int event)
{
- _MSG("UI::handle event=%d\n", 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
- // (not whether numlock is on for example)
- unsigned modifier = event_state() & (SHIFT | CTRL | ALT | META);
+ // We're only interested in some flags
+ unsigned modifier = event_state() & (SHIFT | CTRL | ALT);
- // Let FLTK pass these events to child widgets.
if (event == KEY) {
- if (k == UpKey || k == DownKey || k == SpaceKey ||
- k == LeftKey || k == RightKey)
- return 0;
- // Ignore Escape for main window.
- if (k == EscapeKey)
- ret = 1;
+ return 0; // Receive as shortcut
} else if (event == SHORTCUT) {
- // Handle these shortcuts here.
+ // Handle keyboard shortcuts here.
if (modifier == CTRL) {
if (k == 'b') {
- a_UIcmd_book(user_data());
+ a_UIcmd_book(this->window()->user_data());
ret = 1;
} else if (k == 'f') {
set_findbar_visibility(1);
ret = 1;
} else if (k == 'l') {
- if (Panelmode == UI_HIDDEN) {
- set_panelmode(UI_TEMPORARILY_SHOW_PANELS);
- }
focus_location();
ret = 1;
} else if (k == 'n') {
- a_UIcmd_browser_window_new(w(), h(), this);
+ a_UIcmd_browser_window_new(w(), h(), this->window()->user_data());
ret = 1;
} else if (k == 'o') {
- a_UIcmd_open_file(user_data());
+ a_UIcmd_open_file(this->window()->user_data());
ret = 1;
} else if (k == 'q') {
- a_UIcmd_close_bw(user_data());
+ a_UIcmd_close_bw(this->window()->user_data());
ret = 1;
} else if (k == 'r') {
- a_UIcmd_reload(user_data());
+ a_UIcmd_reload(this->window()->user_data());
ret = 1;
} else if (k == 's') {
- a_UIcmd_search_dialog(user_data());
+ a_UIcmd_search_dialog(this->window()->user_data());
ret = 1;
} else if (k == ' ') {
panelmode_cb_i();
ret = 1;
}
+ } else {
+ // Back and Forward navigation shortcuts
+ if (modifier == 0 && (k == BackSpaceKey || k == ',')) {
+ a_UIcmd_back(this->window()->user_data());
+ ret = 1;
+ } else if ((modifier == 0 && k == '.') ||
+ (modifier == SHIFT && k == BackSpaceKey)) {
+ a_UIcmd_forw(this->window()->user_data());
+ ret = 1;
+ }
}
- if (event_key_state(LeftAltKey) && modifier == ALT && k == 'q') {
- a_UIcmd_close_all_bw();
- ret = 1;
- }
-
- // Back and Forward navigation shortcuts
- if ((modifier == 0 && k == BackSpaceKey) ||
- (modifier == 0 && k == ',')) {
- a_UIcmd_back(user_data());
- ret = 1;
- } else if ((modifier == SHIFT && k == BackSpaceKey) ||
- (modifier == 0 &&k == '.')) {
- a_UIcmd_forw(user_data());
- ret = 1;
- }
+ } else if (event == FOCUS_CHANGE) {
+ // The "bw" for this tab is stored in the parent window.
+ // Update "bw" each time we switch tabs.
+ window()->user_data(vbw());
+ ret = 0;
}
- if (ret == 0) {
- ret = Window::handle(event);
- }
+ if (!ret)
+ ret = Group::handle(event);
return ret;
+
+ // if (event_key_state(LeftAltKey) && modifier == ALT && k == 'q') {
+ // a_UIcmd_close_all_bw();
+ // ret = 1;
+ // }
}
@@ -850,15 +838,27 @@ void UI::set_location(const char *str)
/*
* Focus location entry.
+ * If it's not visible, show it until the callback is done.
*/
void UI::focus_location()
{
+ if (get_panelmode() == UI_HIDDEN) {
+ set_panelmode(UI_TEMPORARILY_SHOW_PANELS);
+ }
Location->take_focus();
// Make text selected when already focused.
Location->position(Location->size(), 0);
}
/*
+ * Focus Main area.
+ */
+void UI::focus_main()
+{
+ Main->take_focus();
+}
+
+/*
* Set a new message in the status bar.
*/
void UI::set_status(const char *str)
@@ -1074,9 +1074,25 @@ void UI::set_page_title(const char *label)
{
char title[128];
+ dReturn_if_fail(label != NULL);
+
snprintf(title, 128, "Dillo: %s", label);
- this->copy_label(title);
- this->redraw_label();
+ this->window()->copy_label(title);
+ this->window()->redraw_label();
+
+ if (tabs() && *label) {
+ const size_t tab_chars = 18;
+ snprintf(title, tab_chars + 1, "%s", label);
+ if (strlen(label) > tab_chars)
+ snprintf(title + tab_chars, 4, "...");
+ this->copy_label(title);
+ this->redraw_label();
+
+ // Disabled because of a bug in fltk::Tabgroup
+ //dFree(TabTooltip);
+ //TabTooltip = dStrdup(label);
+ //this->tooltip(TabTooltip);
+ }
}
/*
diff --git a/src/ui.hh b/src/ui.hh
index d99bfef4..45659aba 100644
--- a/src/ui.hh
+++ b/src/ui.hh
@@ -12,6 +12,7 @@
#include <fltk/Image.h>
#include <fltk/MultiImage.h>
#include <fltk/MenuBuild.h>
+#include <fltk/TabGroup.h>
#include "findbar.hh"
@@ -36,18 +37,22 @@ typedef enum {
} UIPanelmode;
// Private class
-class NewProgressBox;
+class CustProgressBox;
//
// UI class definition -------------------------------------------------------
//
-class UI : public fltk::Window {
+class UI : public fltk::Group {
+ void *Bw;
+ TabGroup *Tabs;
+ char *TabTooltip;
+
Group *TopGroup;
Button *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks,
*Clear, *Search, *FullScreen, *ImageLoad, *BugMeter;
Input *Location;
PackedGroup *ProgBox;
- NewProgressBox *PProg, *IProg;
+ CustProgressBox *PProg, *IProg;
Image *ImgLeftIns, *ImgLeftSens, *ImgRightIns, *ImgRightSens,
*ImgStopIns, *ImgStopSens, *ImgFullScreenOn, *ImgFullScreenOff,
*ImgImageLoadOn, *ImgImageLoadOff, *ImgMeterOK, *ImgMeterBug,
@@ -75,7 +80,7 @@ class UI : public fltk::Window {
void delete_status_panel_images();
public:
- UI(int w, int h, const char* label = 0, const UI *cur_ui = NULL);
+ UI(int x,int y,int w,int h, const char* label = 0, const UI *cur_ui=NULL);
~UI();
// To manage what events to catch and which to let pass
@@ -84,6 +89,7 @@ public:
const char *get_location();
void set_location(const char *str);
void focus_location();
+ void focus_main();
void set_status(const char *str);
void set_page_prog(size_t nbytes, int cmd);
void set_img_prog(int n_img, int t_img, int cmd);
@@ -96,10 +102,14 @@ public:
void set_panelmode(UIPanelmode mode);
UIPanelmode get_panelmode();
void set_findbar_visibility(bool visible);
-
Widget *fullscreen_button() { return FullScreen; }
void fullscreen_toggle() { FullScreen->do_callback(); }
+ TabGroup *tabs() { return Tabs; }
+ void tabs(TabGroup *tabs) { Tabs = tabs; }
+ void *vbw() { return Bw; }
+ void vbw(void *v_bw) { Bw = v_bw; }
+
// Hooks to method callbacks
void panel_cb_i();
void color_change_cb_i();
diff --git a/src/uicmd.cc b/src/uicmd.cc
index ca716692..7e77096c 100644
--- a/src/uicmd.cc
+++ b/src/uicmd.cc
@@ -16,6 +16,7 @@
#include <stdarg.h>
#include <math.h> /* for rint */
#include <fltk/Widget.h>
+#include <fltk/TabGroup.h>
#include "dir.h"
#include "ui.hh"
@@ -32,53 +33,100 @@
#include "nav.h"
+// Handy macro
+#define BW2UI(bw) ((UI*)(bw->ui))
+
// Platform idependent part
using namespace dw::core;
// FLTK related
using namespace dw::fltk;
-typedef struct {
- UI *ui;
- BrowserWindow *bw;
-} Uibw;
/*
* Local data
*/
-// A matching table for all open ui/bw pairs
-// BUG: must be dynamic.
-static Uibw uibws[32];
-static int uibws_num = 0, uibws_max = 32;
-
static char *save_dir = NULL;
using namespace fltk;
+//
+// For custom handling of keyboard
+//
+class CustTabGroup : public fltk::TabGroup {
+public:
+ CustTabGroup (int x, int y, int ww, int wh, const char *lbl=0) :
+ TabGroup(x,y,ww,wh,lbl) {};
+ int handle(int e) {
+ // Don't focus with arrow keys
+ _MSG("CustTabGroup::handle %d\n", e);
+ int k = event_key();
+ // We're only interested in some flags
+ unsigned modifier = event_state() & (SHIFT | CTRL | ALT);
+ if (e == KEY) {
+ if (k == UpKey || k == DownKey || k == TabKey) {
+ return 0;
+ } else if (k == LeftKey || k == RightKey) {
+ if (modifier == SHIFT) {
+ int i = value();
+ if (k == LeftKey) {i = i ? i-1 : children()-1;}
+ else {i++; if (i >= children()) i = 0;}
+ if (value(i)) do_callback();
+ return 1;
+ }
+ return 0;
+ }
+ }
+ return TabGroup::handle(e);
+ }
+};
+
/*
* Create a new UI and its associated BrowserWindow data structure.
* Use style from v_ui. If non-NULL it must be of type UI*.
*/
-BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *v_ui)
+BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *vbw)
{
+ static TabGroup *DilloTabs = NULL;
+ BrowserWindow *old_bw = (BrowserWindow*)vbw;
+ BrowserWindow *new_bw = NULL;
+
if (ww <= 0 || wh <= 0) {
// Set default geometry from dillorc.
ww = prefs.width;
wh = prefs.height;
}
+ if (!DilloTabs) {
+ {Window *o = new Window(ww, wh);
+ o->shortcut(0); // Ignore Escape
+ o->clear_double_buffer();
+ DilloTabs = new CustTabGroup(0, 0, ww, wh);
+ DilloTabs->selection_color(156);
+ //DilloTabs->clear_tab_to_focus();
+ o->add(DilloTabs);
+ }
+ wh -= 20;
+ }
+
// Create and set the UI
- UI *new_ui = new UI(ww, wh, "Dillo: UI", (UI*) v_ui);
+ UI *new_ui = new UI(0, 20, ww, wh, "Label", old_bw ? BW2UI(old_bw) : NULL);
new_ui->set_status("http://www.dillo.org/");
+ new_ui->tabs(DilloTabs);
//new_ui->set_location("http://dillo.org/");
//new_ui->customize(12);
- if (v_ui == NULL && prefs.xpos >= 0 && prefs.ypos >= 0) {
+ DilloTabs->add(new_ui);
+ DilloTabs->resizable(new_ui);
+ DilloTabs->window()->resizable(new_ui);
+ DilloTabs->window()->show();
+
+ if (old_bw == NULL && prefs.xpos >= 0 && prefs.ypos >= 0) {
// position the first window according to preferences
fltk::Rectangle r;
- new_ui->borders(&r);
+ new_ui->window()->borders(&r);
// borders() gives x and y border sizes as negative values
- new_ui->position(prefs.xpos - r.x(), prefs.ypos - r.y());
+ new_ui->window()->position(prefs.xpos - r.x(), prefs.ypos - r.y());
}
// Now create the Dw render layout and viewport
@@ -93,24 +141,16 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *v_ui)
viewport->setScrollStep((int) rint(14.0 * prefs.font_factor));
// Now, create a new browser window structure
- BrowserWindow *new_bw = a_Bw_new();
+ new_bw = a_Bw_new();
+
+ // Store new_bw for callback data inside UI
+ new_ui->vbw(new_bw);
- // Set new_bw as callback data for UI
- new_ui->user_data(new_bw);
// 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;
- // insert the new ui/bw pair in the table
- if (uibws_num < uibws_max) {
- uibws[uibws_num].ui = new_ui;
- uibws[uibws_num].bw = new_bw;
- uibws_num++;
- }
-
- new_ui->show();
-
return new_bw;
}
@@ -120,12 +160,19 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *v_ui)
void a_UIcmd_close_bw(void *vbw)
{
BrowserWindow *bw = (BrowserWindow *)vbw;
- UI *ui = (UI*)bw->ui;
+ UI *ui = BW2UI(bw);
Layout *layout = (Layout*)bw->render_layout;
MSG("a_UIcmd_close_bw\n");
a_Bw_stop_clients(bw, BW_Root + BW_Img + Bw_Force);
delete(layout);
+ if (ui->tabs()) {
+ ui->tabs()->remove(ui);
+ if (ui->tabs()->value() != -1)
+ ui->tabs()->selected_child()->take_focus();
+ else
+ ui->tabs()->window()->hide();
+ }
delete(ui);
a_Bw_free(bw);
}
@@ -562,8 +609,6 @@ void a_UIcmd_nav_jump(BrowserWindow *bw, int offset, int new_bw)
// UI binding functions -------------------------------------------------------
-#define BW2UI(bw) ((UI*)(bw->ui))
-
/*
* Return browser window width and height
*/
@@ -757,3 +802,20 @@ void a_UIcmd_findtext_reset(BrowserWindow *bw)
a_UIcmd_set_msg(bw, "");
}
+/*
+ * Focus the rendered area.
+ */
+void a_UIcmd_focus_main_area(BrowserWindow *bw)
+{
+ BW2UI(bw)->focus_main();
+}
+
+/*
+ * Focus the location bar.
+ */
+void a_UIcmd_focus_location(void *vbw)
+{
+ BrowserWindow *bw = (BrowserWindow*)vbw;
+ BW2UI(bw)->focus_location();
+}
+
diff --git a/src/uicmd.hh b/src/uicmd.hh
index b469beef..1dbf0d99 100644
--- a/src/uicmd.hh
+++ b/src/uicmd.hh
@@ -8,7 +8,7 @@ extern "C" {
#endif /* __cplusplus */
-BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *v_ui);
+BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *v_bw);
void a_UIcmd_open_urlstr(void *vbw, const char *urlstr);
void a_UIcmd_open_url(BrowserWindow *bw, const DilloUrl *url);
void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url);
@@ -31,6 +31,8 @@ void a_UIcmd_fullscreen_toggle(BrowserWindow *bw);
void a_UIcmd_findtext_dialog(BrowserWindow *bw);
void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key, int case_sens);
void a_UIcmd_findtext_reset(BrowserWindow *bw);
+void a_UIcmd_focus_main_area(BrowserWindow *bw);
+void a_UIcmd_focus_location(void *vbw);
void a_UIcmd_page_popup(void *vbw, const DilloUrl *url,
const char *bugs_txt, bool_t unloaded_imgs);
void a_UIcmd_link_popup(void *vbw, const DilloUrl *url);