summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbeng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-05 01:45:00 +0000
committerbeng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-05 01:45:00 +0000
commit85b2310f77ff3dd435f69a2af1a16850ad204489 (patch)
tree2bbeb905e39bf47fe8504f73514914ebe72fe911
parentb95efdd62ec71230dab3ba599cecc62c7e2e92a2 (diff)
downloadchromium_src-85b2310f77ff3dd435f69a2af1a16850ad204489.zip
chromium_src-85b2310f77ff3dd435f69a2af1a16850ad204489.tar.gz
chromium_src-85b2310f77ff3dd435f69a2af1a16850ad204489.tar.bz2
Add the TabStrip to the BrowserView2. (hooked up for OpaqueFrame only at this point). Make non-client hittest logic mostly work. Window is somewhat interactive again. Yay!
B=1031854 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@359 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/tabs/tab_strip.cc19
-rw-r--r--chrome/browser/tabs/tab_strip.h6
-rw-r--r--chrome/browser/views/frame/browser_frame.h5
-rw-r--r--chrome/browser/views/frame/browser_view2.cc57
-rw-r--r--chrome/browser/views/frame/browser_view2.h3
-rw-r--r--chrome/browser/views/frame/opaque_frame.cc13
-rw-r--r--chrome/browser/views/frame/opaque_frame.h6
-rw-r--r--chrome/browser/views/frame/opaque_non_client_view.cc10
-rw-r--r--chrome/browser/views/frame/opaque_non_client_view.h3
9 files changed, 119 insertions, 3 deletions
diff --git a/chrome/browser/tabs/tab_strip.cc b/chrome/browser/tabs/tab_strip.cc
index e6539a9..0c85bec 100644
--- a/chrome/browser/tabs/tab_strip.cc
+++ b/chrome/browser/tabs/tab_strip.cc
@@ -494,6 +494,25 @@ bool TabStrip::CanProcessInputEvents() const {
return IsAnimating() == NULL;
}
+bool TabStrip::PointIsWithinWindowCaption(const CPoint& point) {
+ ChromeViews::View* v = GetViewForPoint(point);
+
+ // If there is no control at this location, claim the hit was in the title
+ // bar to get a move action.
+ if (v == this)
+ return true;
+
+ // If the point is within the bounds of a Tab, the point can be considered
+ // part of the caption if there are no available drag operations for the Tab.
+ if (v->GetClassName() == Tab::kTabClassName && !HasAvailableDragActions())
+ return true;
+
+ // All other regions, including the new Tab button, should be considered part
+ // of the containing Window's client area so that regular events can be
+ // processed for them.
+ return false;
+}
+
bool TabStrip::IsCompatibleWith(TabStrip* other) {
return model_->profile() == other->model()->profile();
}
diff --git a/chrome/browser/tabs/tab_strip.h b/chrome/browser/tabs/tab_strip.h
index 64195a3..ec1e555 100644
--- a/chrome/browser/tabs/tab_strip.h
+++ b/chrome/browser/tabs/tab_strip.h
@@ -90,6 +90,12 @@ class TabStrip : public ChromeViews::View,
// not be allowed to interact with the TabStrip.
bool CanProcessInputEvents() const;
+ // Returns true if the specified point (in TabStrip coordinates) is within a
+ // portion of the TabStrip that should be treated as the containing Window's
+ // titlebar for dragging purposes.
+ // TODO(beng): (Cleanup) should be const, but GetViewForPoint isn't, so fie!
+ bool PointIsWithinWindowCaption(const CPoint& point);
+
// Return true if this tab strip is compatible with the provided tab strip.
// Compatible tab strips can transfer tabs during drag and drop.
bool IsCompatibleWith(TabStrip* other);
diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h
index 55b22fe..0431486 100644
--- a/chrome/browser/views/frame/browser_frame.h
+++ b/chrome/browser/views/frame/browser_frame.h
@@ -37,6 +37,7 @@ class Window;
namespace gfx {
class Rect;
}
+class TabStrip;
///////////////////////////////////////////////////////////////////////////////
// BrowserFrame
@@ -47,6 +48,10 @@ class Rect;
//
class BrowserFrame {
public:
+ // Returns the bounds that should be used to size and position the specified
+ // TabStrip.
+ virtual gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const = 0;
+
// Returns the ChromeViews::Window associated with this frame.
virtual ChromeViews::Window* GetWindow() = 0;
diff --git a/chrome/browser/views/frame/browser_view2.cc b/chrome/browser/views/frame/browser_view2.cc
index af62ab1..b042fbd 100644
--- a/chrome/browser/views/frame/browser_view2.cc
+++ b/chrome/browser/views/frame/browser_view2.cc
@@ -31,6 +31,7 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/tab_contents_container_view.h"
+#include "chrome/browser/tabs/tab_strip.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/download_shelf_view.h"
@@ -42,6 +43,7 @@
// static
static const int kToolbarTabStripVerticalOverlap = 3;
+static const int kTabShadowSize = 2;
static const int kStatusBubbleHeight = 20;
static const int kStatusBubbleOffset = 2;
@@ -82,6 +84,10 @@ gfx::Rect BrowserView2::GetClientAreaBounds() const {
void BrowserView2::Init() {
SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME));
+ tabstrip_ = new TabStrip(browser_->tabstrip_model());
+ tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP));
+ AddChildView(tabstrip_);
+
toolbar_ = new BrowserToolbarView(browser_->controller(), browser_.get());
AddChildView(toolbar_);
toolbar_->SetID(VIEW_ID_TOOLBAR);
@@ -305,7 +311,49 @@ bool BrowserView2::CanClose() const {
}
int BrowserView2::NonClientHitTest(const gfx::Point& point) {
- return HTNOWHERE;
+ // First learn about the kind of frame we dwell within...
+ WINDOWINFO wi;
+ wi.cbSize = sizeof(wi);
+ GetWindowInfo(frame_->GetWindow()->GetHWND(), &wi);
+
+ // Since we say that our client area extends to the top of the window (in
+ // the frame's WM_NCHITTEST handler.
+ CRect lb;
+ GetLocalBounds(&lb, true);
+ if (lb.PtInRect(point.ToPOINT())) {
+ if (point.y() < static_cast<int>(wi.cyWindowBorders))
+ return HTTOP;
+ }
+
+ CPoint point_in_view_coords(point.ToPOINT());
+ View::ConvertPointToView(GetParent(), this, &point_in_view_coords);
+ // TODO(beng): support IsTabStripVisible().
+ if (/* IsTabStripVisible() && */tabstrip_->HitTest(point_in_view_coords) &&
+ tabstrip_->CanProcessInputEvents()) {
+ ChromeViews::Window* window = frame_->GetWindow();
+ // The top few pixels of the TabStrip are a drop-shadow - as we're pretty
+ // starved of dragable area, let's give it to window dragging (this also
+ // makes sense visually).
+ if (!window->IsMaximized() && point_in_view_coords.y < kTabShadowSize)
+ return HTCAPTION;
+
+ if (tabstrip_->PointIsWithinWindowCaption(point_in_view_coords))
+ return HTCAPTION;
+
+ return HTCLIENT;
+ }
+
+ // If the point's y coordinate is below the top of the toolbar and otherwise
+ // within the bounds of this view, the point is considered to be within the
+ // client area.
+ CRect bounds;
+ GetBounds(&bounds);
+ bounds.top += toolbar_->GetY();
+ if (gfx::Rect(bounds).Contains(point.x(), point.y()))
+ return HTCLIENT;
+
+ // If the point is somewhere else, delegate to the default implementation.
+ return ClientView::NonClientHitTest(point);
}
///////////////////////////////////////////////////////////////////////////////
@@ -339,7 +387,12 @@ void BrowserView2::ViewHierarchyChanged(bool is_add,
// BrowserView2, private:
int BrowserView2::LayoutTabStrip() {
- return 40; // TODO(beng): hook this up.
+ gfx::Rect tabstrip_bounds = frame_->GetBoundsForTabStrip(tabstrip_);
+ // TODO(beng): account for OTR avatar.
+ tabstrip_->SetBounds(tabstrip_bounds.x(), tabstrip_bounds.y(),
+ tabstrip_bounds.width(), tabstrip_bounds.height());
+ return tabstrip_bounds.bottom();
+ // TODO(beng): support tabstrip-less windows.
}
int BrowserView2::LayoutToolbar(int top) {
diff --git a/chrome/browser/views/frame/browser_view2.h b/chrome/browser/views/frame/browser_view2.h
index 52973ef..206da40 100644
--- a/chrome/browser/views/frame/browser_view2.h
+++ b/chrome/browser/views/frame/browser_view2.h
@@ -174,6 +174,9 @@ class BrowserView2 : public BrowserWindow,
ChromeViews::View* active_info_bar_;
ChromeViews::View* active_download_shelf_;
+ // The TabStrip.
+ TabStrip* tabstrip_;
+
// The Toolbar containing the navigation buttons, menus and the address bar.
BrowserToolbarView* toolbar_;
diff --git a/chrome/browser/views/frame/opaque_frame.cc b/chrome/browser/views/frame/opaque_frame.cc
index 702c650..77260e1 100644
--- a/chrome/browser/views/frame/opaque_frame.cc
+++ b/chrome/browser/views/frame/opaque_frame.cc
@@ -29,6 +29,7 @@
#include "chrome/browser/views/frame/opaque_frame.h"
+#include "chrome/browser/tabs/tab_strip.h"
#include "chrome/browser/views/frame/browser_view2.h"
#include "chrome/browser/views/frame/opaque_non_client_view.h"
#include "chrome/views/window_delegate.h"
@@ -56,6 +57,18 @@ gfx::Rect OpaqueFrame::GetContentsBounds() const {
///////////////////////////////////////////////////////////////////////////////
// OpaqueFrame, BrowserFrame implementation:
+gfx::Rect OpaqueFrame::GetBoundsForTabStrip(TabStrip* tabstrip) const {
+ return GetOpaqueNonClientView()->GetBoundsForTabStrip(tabstrip);
+}
+
ChromeViews::Window* OpaqueFrame::GetWindow() {
return this;
}
+
+///////////////////////////////////////////////////////////////////////////////
+// OpaqueFrame, private:
+
+OpaqueNonClientView* OpaqueFrame::GetOpaqueNonClientView() const {
+ // We can safely assume that this conversion is true.
+ return static_cast<OpaqueNonClientView*>(non_client_view_);
+}
diff --git a/chrome/browser/views/frame/opaque_frame.h b/chrome/browser/views/frame/opaque_frame.h
index 78b6475..7730038 100644
--- a/chrome/browser/views/frame/opaque_frame.h
+++ b/chrome/browser/views/frame/opaque_frame.h
@@ -37,6 +37,8 @@ class BrowserView2;
namespace ChromeViews {
class Window;
}
+class OpaqueNonClientView;
+class TabStrip;
///////////////////////////////////////////////////////////////////////////////
// OpaqueFrame
@@ -60,9 +62,13 @@ class OpaqueFrame : public BrowserFrame,
gfx::Rect GetContentsBounds() const;
// Overridden from BrowserFrame:
+ virtual gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const;
virtual ChromeViews::Window* GetWindow();
private:
+ // Return a pointer to the concrete type of our non-client view.
+ OpaqueNonClientView* GetOpaqueNonClientView() const;
+
// The BrowserView2 is our ClientView. This is a pointer to it.
BrowserView2* browser_view_;
diff --git a/chrome/browser/views/frame/opaque_non_client_view.cc b/chrome/browser/views/frame/opaque_non_client_view.cc
index 3378d36..4ff345c 100644
--- a/chrome/browser/views/frame/opaque_non_client_view.cc
+++ b/chrome/browser/views/frame/opaque_non_client_view.cc
@@ -30,6 +30,7 @@
#include "chrome/browser/views/frame/opaque_non_client_view.h"
#include "chrome/app/theme/theme_resources.h"
+#include "chrome/browser/tabs/tab_strip.h"
#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/common/gfx/chrome_font.h"
#include "chrome/common/gfx/path.h"
@@ -335,7 +336,7 @@ static const int kWindowIconTopOffset = 5;
static const int kTitleTopOffset = 6;
static const int kWindowIconTitleSpacing = 3;
static const int kTitleBottomSpacing = 6;
-static const int kNoTitleTopSpacing = 8;
+static const int kNoTitleTopSpacing = 10;
static const int kResizeAreaSize = 5;
static const int kResizeAreaNorthSize = 3;
static const int kResizeAreaCornerSize = 16;
@@ -416,6 +417,13 @@ OpaqueNonClientView::OpaqueNonClientView(OpaqueFrame* frame, bool is_otr)
OpaqueNonClientView::~OpaqueNonClientView() {
}
+gfx::Rect OpaqueNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) {
+ int tabstrip_height = tabstrip->GetPreferredHeight();
+ int tabstrip_x = frame_->client_view()->GetX() - 4;
+ return gfx::Rect(tabstrip_x, frame_->client_view()->GetY() - 1,
+ minimize_button_->GetX() - tabstrip_x, tabstrip_height);
+}
+
///////////////////////////////////////////////////////////////////////////////
// OpaqueNonClientView, ChromeViews::BaseButton::ButtonListener implementation:
diff --git a/chrome/browser/views/frame/opaque_non_client_view.h b/chrome/browser/views/frame/opaque_non_client_view.h
index bf48c26..70de386 100644
--- a/chrome/browser/views/frame/opaque_non_client_view.h
+++ b/chrome/browser/views/frame/opaque_non_client_view.h
@@ -35,6 +35,7 @@
#include "chrome/views/button.h"
class OpaqueFrame;
+class TabStrip;
class WindowResources;
class OpaqueNonClientView : public ChromeViews::NonClientView,
@@ -46,6 +47,8 @@ class OpaqueNonClientView : public ChromeViews::NonClientView,
OpaqueNonClientView(OpaqueFrame* frame, bool is_otr);
virtual ~OpaqueNonClientView();
+ gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip);
+
protected:
// Overridden from ChromeViews::BaseButton::ButtonListener:
virtual void ButtonPressed(ChromeViews::BaseButton* sender);