diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/tabs/tab.cc | 41 | ||||
-rw-r--r-- | chrome/browser/tabs/tab.h | 7 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip.cc | 36 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip.h | 7 |
4 files changed, 91 insertions, 0 deletions
diff --git a/chrome/browser/tabs/tab.cc b/chrome/browser/tabs/tab.cc index 4482079..f855701 100644 --- a/chrome/browser/tabs/tab.cc +++ b/chrome/browser/tabs/tab.cc @@ -6,6 +6,8 @@ #include "base/gfx/size.h" #include "chrome/views/view_container.h" +#include "chrome/common/gfx/chrome_canvas.h" +#include "chrome/common/gfx/path.h" #include "chrome/common/resource_bundle.h" #include "chrome/views/chrome_menu.h" #include "chrome/views/tooltip_manager.h" @@ -13,6 +15,10 @@ const std::string Tab::kTabClassName = "browser/tabs/Tab"; +static const SkScalar kTabCapWidth = 15; +static const SkScalar kTabTopCurveWidth = 4; +static const SkScalar kTabBottomCurveWidth = 3; + class TabContextMenuController : public ChromeViews::MenuDelegate { public: explicit TabContextMenuController(Tab* tab) @@ -120,6 +126,13 @@ bool Tab::IsSelected() const { /////////////////////////////////////////////////////////////////////////////// // Tab, ChromeViews::View overrides: +bool Tab::HitTest(const CPoint &l) const { + gfx::Path path; + MakePathForTab(&path); + ScopedHRGN rgn(path.CreateHRGN()); + return !!PtInRegion(rgn, l.x, l.y); +} + bool Tab::OnMousePressed(const ChromeViews::MouseEvent& event) { if (event.IsOnlyLeftMouseButton()) { // Store whether or not we were selected just now... we only want to be @@ -198,3 +211,31 @@ void Tab::ButtonPressed(ChromeViews::BaseButton* sender) { delegate_->CloseTab(this); } +/////////////////////////////////////////////////////////////////////////////// +// Tab, private: + +void Tab::MakePathForTab(gfx::Path* path) const { + DCHECK(path); + + SkScalar h = SkIntToScalar(GetHeight()); + SkScalar w = SkIntToScalar(GetWidth()); + + path->moveTo(0, h); + + // Left end cap. + path->lineTo(kTabBottomCurveWidth, h - kTabBottomCurveWidth); + path->lineTo(kTabCapWidth - kTabTopCurveWidth, kTabTopCurveWidth); + path->lineTo(kTabCapWidth, 0); + + // Connect to the right cap. + path->lineTo(w - kTabCapWidth, 0); + + // Right end cap. + path->lineTo(w - kTabCapWidth - kTabTopCurveWidth, kTabTopCurveWidth); + path->lineTo(w - kTabBottomCurveWidth, h - kTabBottomCurveWidth); + path->lineTo(w, h); + + // Close out the path. + path->lineTo(0, h); + path->close(); +} diff --git a/chrome/browser/tabs/tab.h b/chrome/browser/tabs/tab.h index 802156b..10346ef 100644 --- a/chrome/browser/tabs/tab.h +++ b/chrome/browser/tabs/tab.h @@ -10,6 +10,7 @@ #include "chrome/views/base_button.h" namespace gfx { +class Path; class Point; } class TabContents; @@ -83,6 +84,8 @@ class Tab : public TabRenderer, // TabRenderer overrides: virtual bool IsSelected() const; + // ChromeViews::View overrides: + virtual bool HitTest(const CPoint &l) const; private: // ChromeViews::View overrides: virtual bool OnMousePressed(const ChromeViews::MouseEvent& event); @@ -104,6 +107,10 @@ class Tab : public TabRenderer, // ChromeViews::BaseButton::ButtonListener overrides: virtual void ButtonPressed(ChromeViews::BaseButton* sender); + // Creates a path that contains the clickable region of the tab's visual + // representation. Used by GetViewForPoint for hit-testing. + void MakePathForTab(gfx::Path* path) const; + // An instance of a delegate object that can perform various actions based on // user gestures. TabDelegate* delegate_; diff --git a/chrome/browser/tabs/tab_strip.cc b/chrome/browser/tabs/tab_strip.cc index efb4763..aed87a1 100644 --- a/chrome/browser/tabs/tab_strip.cc +++ b/chrome/browser/tabs/tab_strip.cc @@ -689,6 +689,36 @@ void TabStrip::SetAccessibleName(const std::wstring& name) { accessible_name_.assign(name); } +ChromeViews::View* TabStrip::GetViewForPoint(const CPoint& point) { + return GetViewForPoint(point, false); +} + +ChromeViews::View* TabStrip::GetViewForPoint(const CPoint& point, + bool can_create_floating) { + // Return any view that isn't a Tab or this TabStrip immediately. We don't + // want to interfere. + ChromeViews::View* v = View::GetViewForPoint(point, can_create_floating); + if (v && v != this && v->GetClassName() != Tab::kTabClassName) + return v; + + // The display order doesn't necessarily match the child list order, so we + // walk the display list hit-testing Tabs. Since the selected tab always + // renders on top of adjacent tabs, it needs to be hit-tested before any + // left-adjacent Tab, so we look ahead for it as we walk. + int tab_count = GetTabCount(); + for (int i = 0; i < tab_count; ++i) { + Tab* next_tab = i < (tab_count - 1) ? GetTabAt(i + 1) : NULL; + if (next_tab && next_tab->IsSelected() && IsPointInTab(next_tab, point)) + return next_tab; + Tab* tab = GetTabAt(i); + if (IsPointInTab(tab, point)) + return tab; + } + + // No need to do any floating view stuff, we don't use them in the TabStrip. + return this; +} + /////////////////////////////////////////////////////////////////////////////// // TabStrip, TabStripModelObserver implementation: @@ -1476,3 +1506,9 @@ int TabStrip::GetAvailableWidthForTabs(Tab* last_tab) const { return last_tab->GetX() + last_tab->GetWidth(); } +bool TabStrip::IsPointInTab(Tab* tab, const CPoint& point_in_tabstrip_coords) { + CPoint point_in_tab_coords(point_in_tabstrip_coords); + View::ConvertPointToView(this, tab, &point_in_tab_coords); + return tab->HitTest(point_in_tab_coords); +} + diff --git a/chrome/browser/tabs/tab_strip.h b/chrome/browser/tabs/tab_strip.h index 89151d8..ad14213 100644 --- a/chrome/browser/tabs/tab_strip.h +++ b/chrome/browser/tabs/tab_strip.h @@ -114,6 +114,9 @@ class TabStrip : public ChromeViews::View, virtual bool GetAccessibleRole(VARIANT* role); virtual bool GetAccessibleName(std::wstring* name); virtual void SetAccessibleName(const std::wstring& name); + virtual ChromeViews::View* GetViewForPoint(const CPoint& point); + virtual ChromeViews::View* GetViewForPoint(const CPoint& point, + bool can_create_floating); protected: // TabStripModelObserver implementation: @@ -268,6 +271,10 @@ class TabStrip : public ChromeViews::View, // Calculates the available width for tabs, assuming a Tab is to be closed. int GetAvailableWidthForTabs(Tab* last_tab) const; + // Returns true if the specified point in TabStrip coords is within the + // hit-test region of the specified Tab. + bool IsPointInTab(Tab* tab, const CPoint& point_in_tabstrip_coords); + // -- Member Variables ------------------------------------------------------ // Our model. |