Implemented a completely new tab view framework:

* Tabs are only visible when there are more than one.
* Tabs have close buttons.
* Much more flexible, adding scrolling and left/right buttons when there are
  more tabs than room will be easy. Also drag&drop of tabs.
I've tested this quite a bit, hopefully there are no regressions.


git-svn-id: http://svn.haiku-os.org/webpositive/webkit/trunk@228 94f232f2-1747-11df-bad5-a5bfde151594
This commit is contained in:
stippi 2010-02-26 19:02:24 +00:00
parent 1c3a676322
commit 72664707fa
4 changed files with 1055 additions and 60 deletions

View File

@ -77,8 +77,6 @@ enum {
TEXT_HIDE_FIND_GROUP = 'hfnd', TEXT_HIDE_FIND_GROUP = 'hfnd',
TEXT_FIND_NEXT = 'fndn', TEXT_FIND_NEXT = 'fndn',
TEXT_FIND_PREVIOUS = 'fndp', TEXT_FIND_PREVIOUS = 'fndp',
CLOSE_TAB = 'ctab'
}; };
using namespace WebCore; using namespace WebCore;
@ -97,8 +95,7 @@ LauncherWindow::LauncherWindow(BRect frame, const BMessenger& downloadListener,
B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS) B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS)
, m_downloadListener(downloadListener) , m_downloadListener(downloadListener)
{ {
m_tabView = new WebTabView("tabview", BMessenger(this)); m_tabManager = new TabManager(BMessenger(this));
m_tabView->setTarget(BMessenger(this));
if (toolbarPolicy == HaveToolbar) { if (toolbarPolicy == HaveToolbar) {
// Menu // Menu
@ -196,6 +193,7 @@ LauncherWindow::LauncherWindow(BRect frame, const BMessenger& downloadListener,
// Layout // Layout
AddChild(BGroupLayoutBuilder(B_VERTICAL) AddChild(BGroupLayoutBuilder(B_VERTICAL)
.Add(m_menuBar) .Add(m_menuBar)
.Add(m_tabManager->TabGroup())
.Add(BGridLayoutBuilder(kElementSpacing, kElementSpacing) .Add(BGridLayoutBuilder(kElementSpacing, kElementSpacing)
.Add(m_BackButton, 0, 0) .Add(m_BackButton, 0, 0)
.Add(m_ForwardButton, 1, 0) .Add(m_ForwardButton, 1, 0)
@ -204,8 +202,8 @@ LauncherWindow::LauncherWindow(BRect frame, const BMessenger& downloadListener,
.Add(button, 4, 0) .Add(button, 4, 0)
.SetInsets(kInsetSpacing, kInsetSpacing, kInsetSpacing, kInsetSpacing) .SetInsets(kInsetSpacing, kInsetSpacing, kInsetSpacing, kInsetSpacing)
) )
// .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER))
.Add(m_tabView) .Add(m_tabManager->ContainerView())
.Add(findGroup) .Add(findGroup)
.Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER))
.Add(BGroupLayoutBuilder(B_HORIZONTAL, kElementSpacing) .Add(BGroupLayoutBuilder(B_HORIZONTAL, kElementSpacing)
@ -219,6 +217,7 @@ LauncherWindow::LauncherWindow(BRect frame, const BMessenger& downloadListener,
m_url->MakeFocus(true); m_url->MakeFocus(true);
m_findGroup = layoutItemFor(findGroup); m_findGroup = layoutItemFor(findGroup);
m_tabGroup = layoutItemFor(m_tabManager->TabGroup());
} else { } else {
m_BackButton = 0; m_BackButton = 0;
m_ForwardButton = 0; m_ForwardButton = 0;
@ -344,23 +343,28 @@ void LauncherWindow::MessageReceived(BMessage* message)
be_app->PostMessage(message); be_app->PostMessage(message);
break; break;
case CLOSE_TAB: { case CLOSE_TAB:
if (m_tabView->CountTabs() > 1) if (m_tabManager->CountTabs() > 1) {
delete m_tabView->RemoveTab(m_tabView->Selection()); int32 index;
else if (message->FindInt32("tab index", &index) != B_OK)
index = m_tabManager->SelectedTabIndex();
delete m_tabManager->RemoveTab(index);
updateTabGroupVisibility();
} else
PostMessage(B_QUIT_REQUESTED); PostMessage(B_QUIT_REQUESTED);
break; break;
}
case TAB_CHANGED: { case TAB_CHANGED: {
// This message may be received also when the last tab closed, i.e. with index == -1. // This message may be received also when the last tab closed, i.e. with index == -1.
int32 index = -1; int32 index;
message->FindInt32("index", &index); if (message->FindInt32("tab index", &index) != B_OK)
BWebView* webView = dynamic_cast<BWebView*>(m_tabView->ViewForTab(index)); index = -1;
BWebView* webView = dynamic_cast<BWebView*>(m_tabManager->ViewForTab(index));
if (webView == CurrentWebView())
break;
SetCurrentWebView(webView); SetCurrentWebView(webView);
BTab* tab = m_tabView->TabAt(index); if (webView)
if (tab) updateTitle(webView->MainFrameTitle());
updateTitle(tab->Label());
else else
updateTitle(""); updateTitle("");
if (webView) { if (webView) {
@ -384,8 +388,8 @@ bool LauncherWindow::QuitRequested()
// Iterate over all tabs to delete all BWebViews. // Iterate over all tabs to delete all BWebViews.
// Do this here, so WebKit tear down happens earlier. // Do this here, so WebKit tear down happens earlier.
while (m_tabView->CountTabs() > 0) while (m_tabManager->CountTabs() > 0)
delete m_tabView->RemoveTab(0L); delete m_tabManager->RemoveTab(0L);
SetCurrentWebView(0); SetCurrentWebView(0);
BMessage message(WINDOW_CLOSED); BMessage message(WINDOW_CLOSED);
@ -432,21 +436,22 @@ void LauncherWindow::newTab(const BString& url, bool select, BWebView* webView)
webView = new BWebView("web view"); webView = new BWebView("web view");
webView->WebPage()->SetDownloadListener(m_downloadListener); webView->WebPage()->SetDownloadListener(m_downloadListener);
m_tabView->AddTab(webView); m_tabManager->AddTab(webView, "New tab");
m_tabView->TabAt(m_tabView->CountTabs() - 1)->SetLabel("New tab");
// TODO: Remove when BTabView is fixed...
m_tabView->Invalidate();
if (url.Length()) if (url.Length())
webView->LoadURL(url.String()); webView->LoadURL(url.String());
if (select) { if (select) {
m_tabView->Select(m_tabView->CountTabs() - 1); m_tabManager->SelectTab(m_tabManager->CountTabs() - 1);
SetCurrentWebView(webView); SetCurrentWebView(webView);
NavigationCapabilitiesChanged(false, false, false, webView); NavigationCapabilitiesChanged(false, false, false, webView);
if (m_url) if (m_url) {
m_url->SetText(url.String());
m_url->MakeFocus(true); m_url->MakeFocus(true);
}
} }
updateTabGroupVisibility();
} }
// #pragma mark - Notification API // #pragma mark - Notification API
@ -577,10 +582,9 @@ void LauncherWindow::SetResizable(bool flag, BWebView* view)
void LauncherWindow::TitleChanged(const BString& title, BWebView* view) void LauncherWindow::TitleChanged(const BString& title, BWebView* view)
{ {
for (int32 i = 0; i < m_tabView->CountTabs(); i++) { for (int32 i = 0; i < m_tabManager->CountTabs(); i++) {
if (m_tabView->ViewForTab(i) == view) { if (m_tabManager->ViewForTab(i) == view) {
m_tabView->TabAt(i)->SetLabel(title); m_tabManager->SetTabLabel(i, title);
m_tabView->DrawTabs();
break; break;
} }
} }
@ -653,3 +657,11 @@ void LauncherWindow::updateTitle(const BString& title)
windowTitle << "HaikuLauncher"; windowTitle << "HaikuLauncher";
SetTitle(windowTitle.String()); SetTitle(windowTitle.String());
} }
void LauncherWindow::updateTabGroupVisibility()
{
if (Lock()) {
m_tabGroup->SetVisible(m_tabManager->CountTabs() > 1);
Unlock();
}
}

View File

@ -42,7 +42,7 @@ class BStatusBar;
class BStringView; class BStringView;
class BTextControl; class BTextControl;
class IconButton; class IconButton;
class WebTabView; class TabManager;
class BWebView; class BWebView;
enum ToolbarPolicy { enum ToolbarPolicy {
@ -93,6 +93,7 @@ private:
virtual void AuthenticationChallenge(BMessage* challenge); virtual void AuthenticationChallenge(BMessage* challenge);
void updateTitle(const BString &title); void updateTitle(const BString &title);
void updateTabGroupVisibility();
private: private:
BMessenger m_downloadListener; BMessenger m_downloadListener;
@ -106,9 +107,10 @@ private:
BStringView* m_statusText; BStringView* m_statusText;
BStatusBar* m_loadingProgressBar; BStatusBar* m_loadingProgressBar;
BLayoutItem* m_findGroup; BLayoutItem* m_findGroup;
BLayoutItem* m_tabGroup;
BTextControl* m_findTextControl; BTextControl* m_findTextControl;
BCheckBox* m_findCaseSensitiveCheckBox; BCheckBox* m_findCaseSensitiveCheckBox;
WebTabView* m_tabView; TabManager* m_tabManager;
}; };
#endif // LauncherWindow_h #endif // LauncherWindow_h

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2010 Rene Gollent <rene@gollent.com> * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
* *
* All rights reserved. * All rights reserved.
* *
@ -25,28 +25,52 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef WebTabView_h #ifndef TAB_MANAGER_H
#define WebTabView_h #define TAB_MANAGER_H
#include <Messenger.h> #include <Messenger.h>
#include <TabView.h> #include <TabView.h>
enum { enum {
TAB_CHANGED = 'tcha' TAB_CHANGED = 'tcha',
CLOSE_TAB = 'cltb'
}; };
class WebTabView : public BTabView { class BCardLayout;
public: class BGroupView;
WebTabView(const char *name, const BMessenger& target); class TabContainerView;
virtual ~WebTabView(void);
virtual void Select(int32 tab);
const BMessenger& target() const; class TabManager {
void setTarget(const BMessenger& target); public:
TabManager(const BMessenger& target);
virtual ~TabManager();
void SetTarget(const BMessenger& target);
const BMessenger& Target() const;
BView* TabGroup() const;
BView* ContainerView() const;
BView* ViewForTab(int32 tabIndex) const;
void SelectTab(int32 tabIndex);
int32 SelectedTabIndex() const;
void CloseTab(int32 tabIndex);
void AddTab(BView* view, const char* label,
int32 index = -1);
BView* RemoveTab(int32 index);
int32 CountTabs() const;
void SetTabLabel(int32 tabIndex, const char* label);
private: private:
BMessenger m_target; BGroupView* fTabContainerGroup;
TabContainerView* fTabContainerView;
BView* fContainerView;
BCardLayout* fCardLayout;
BMessenger fTarget;
}; };
#define WebTabView_h #endif // TAB_MANAGER_H
#endif // WebTabView_h