tab.h revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_H_ 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_H_ 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <list> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string> 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/ref_counted.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab_renderer_data.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/layout.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/animation/animation_delegate.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/point.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/context_menu_controller.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/controls/button/button.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/controls/glow_hover_controller.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/view.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TabController; 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace gfx { 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Animation; 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class AnimationContainer; 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Font; 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LinearAnimation; 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MultiAnimation; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace views { 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ImageButton; 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A View that renders a Tab, either in a TabStrip or in a DraggedTabView. 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Tab : public gfx::AnimationDelegate, 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public views::ButtonListener, 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public views::ContextMenuController, 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public views::View { 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The menu button's class name. 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const char kViewClassName[]; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 48 explicit Tab(TabController* controller); 49 virtual ~Tab(); 50 51 TabController* controller() const { return controller_; } 52 53 // Used to set/check whether this Tab is being animated closed. 54 void set_closing(bool closing) { closing_ = closing; } 55 bool closing() const { return closing_; } 56 57 // See description above field. 58 void set_dragging(bool dragging) { dragging_ = dragging; } 59 bool dragging() const { return dragging_; } 60 61 // Sets the container all animations run from. 62 void set_animation_container(gfx::AnimationContainer* container); 63 64 // Set the theme provider - because we get detached, we are frequently 65 // outside of a hierarchy with a theme provider at the top. This should be 66 // called whenever we're detached or attached to a hierarchy. 67 void set_theme_provider(ui::ThemeProvider* provider) { 68 theme_provider_ = provider; 69 } 70 71 // Returns true if this tab is the active tab. 72 bool IsActive() const; 73 74 // Returns true if the tab is selected. 75 bool IsSelected() const; 76 77 // Sets the data this tabs displays. Invokes DataChanged. 78 void SetData(const TabRendererData& data); 79 const TabRendererData& data() const { return data_; } 80 81 // Sets the network state. If the network state changes NetworkStateChanged is 82 // invoked. 83 void UpdateLoadingAnimation(TabRendererData::NetworkState state); 84 85 // Starts/Stops a pulse animation. 86 void StartPulse(); 87 void StopPulse(); 88 89 // Start/stop the mini-tab title animation. 90 void StartMiniTabTitleAnimation(); 91 void StopMiniTabTitleAnimation(); 92 93 // Set the background offset used to match the image in the inactive tab 94 // to the frame image. 95 void set_background_offset(const gfx::Point& offset) { 96 background_offset_ = offset; 97 } 98 99 // Returns true if this tab became the active tab selected in 100 // response to the last ui::ET_GESTURE_BEGIN gesture dispatched to 101 // this tab. Only used for collecting UMA metrics. 102 // See ash/touch/touch_uma.cc. 103 bool tab_activated_with_last_gesture_begin() const { 104 return tab_activated_with_last_gesture_begin_; 105 } 106 107 views::GlowHoverController* hover_controller() { 108 return &hover_controller_; 109 } 110 111 // Returns the minimum possible size of a single unselected Tab. 112 static gfx::Size GetMinimumUnselectedSize(); 113 // Returns the minimum possible size of a selected Tab. Selected tabs must 114 // always show a close button and have a larger minimum size than unselected 115 // tabs. 116 static gfx::Size GetMinimumSelectedSize(); 117 // Returns the preferred size of a single Tab, assuming space is 118 // available. 119 static gfx::Size GetStandardSize(); 120 121 // Returns the width for touch tabs. 122 static int GetTouchWidth(); 123 124 // Returns the width for mini-tabs. Mini-tabs always have this width. 125 static int GetMiniWidth(); 126 127 // Returns the height for immersive mode tabs. 128 static int GetImmersiveHeight(); 129 130 private: 131 friend class TabTest; 132 FRIEND_TEST_ALL_PREFIXES(TabTest, CloseButtonLayout); 133 // The animation object used to swap the favicon with the sad tab icon. 134 class FaviconCrashAnimation; 135 class TabCloseButton; 136 137 // Contains a cached image and the values used to generate it. 138 struct ImageCacheEntry { 139 ImageCacheEntry(); 140 ~ImageCacheEntry(); 141 142 // ID of the resource used. 143 int resource_id; 144 145 // Scale factor we're drawing it. 146 ui::ScaleFactor scale_factor; 147 148 // The image. 149 gfx::ImageSkia image; 150 }; 151 152 typedef std::list<ImageCacheEntry> ImageCache; 153 154 // Overridden from gfx::AnimationDelegate: 155 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; 156 virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE; 157 virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; 158 159 // Overridden from views::ButtonListener: 160 virtual void ButtonPressed(views::Button* sender, 161 const ui::Event& event) OVERRIDE; 162 163 // Overridden from views::ContextMenuController: 164 virtual void ShowContextMenuForView(views::View* source, 165 const gfx::Point& point, 166 ui::MenuSourceType source_type) OVERRIDE; 167 168 // Overridden from views::View: 169 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 170 virtual void Layout() OVERRIDE; 171 virtual void OnThemeChanged() OVERRIDE; 172 virtual const char* GetClassName() const OVERRIDE; 173 virtual bool HasHitTestMask() const OVERRIDE; 174 virtual void GetHitTestMask(gfx::Path* path) const OVERRIDE; 175 virtual bool GetTooltipText(const gfx::Point& p, 176 string16* tooltip) const OVERRIDE; 177 virtual bool GetTooltipTextOrigin(const gfx::Point& p, 178 gfx::Point* origin) const OVERRIDE; 179 virtual ui::ThemeProvider* GetThemeProvider() const OVERRIDE; 180 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 181 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; 182 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; 183 virtual void OnMouseCaptureLost() OVERRIDE; 184 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; 185 virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE; 186 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 187 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; 188 189 // Overridden from ui::EventHandler: 190 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 191 192 // Returns the bounds of the title and icon. 193 const gfx::Rect& GetTitleBounds() const; 194 const gfx::Rect& GetIconBounds() const; 195 196 // Invoked from Layout to adjust the position of the favicon or media 197 // indicator for mini tabs. 198 void MaybeAdjustLeftForMiniTab(gfx::Rect* bounds) const; 199 200 // Invoked from SetData after |data_| has been updated to the new data. 201 void DataChanged(const TabRendererData& old); 202 203 // Paint with the normal tab style. 204 void PaintTab(gfx::Canvas* canvas); 205 206 // Paint with the "immersive mode" light-bar style. 207 void PaintImmersiveTab(gfx::Canvas* canvas); 208 209 // Paint various portions of the Tab 210 void PaintTabBackground(gfx::Canvas* canvas); 211 void PaintInactiveTabBackgroundWithTitleChange( 212 gfx::Canvas* canvas, 213 gfx::MultiAnimation* animation); 214 void PaintInactiveTabBackground(gfx::Canvas* canvas); 215 void PaintInactiveTabBackgroundUsingResourceId(gfx::Canvas* canvas, 216 int tab_id); 217 void PaintActiveTabBackground(gfx::Canvas* canvas); 218 219 // Paints the favicon, media indicator icon, etc., mirrored for RTL if needed. 220 void PaintIcon(gfx::Canvas* canvas); 221 void PaintMediaIndicator(gfx::Canvas* canvas); 222 void PaintTitle(gfx::Canvas* canvas, SkColor title_color); 223 224 // Invoked if data_.network_state changes, or the network_state is not none. 225 void AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, 226 TabRendererData::NetworkState state); 227 228 // Returns the number of favicon-size elements that can fit in the tab's 229 // current size. 230 int IconCapacity() const; 231 232 // Returns whether the Tab should display a favicon. 233 bool ShouldShowIcon() const; 234 235 // Returns whether the Tab should display the media indicator. 236 bool ShouldShowMediaIndicator() const; 237 238 // Returns whether the Tab should display a close button. 239 bool ShouldShowCloseBox() const; 240 241 // Gets the throb value for the tab. When a tab is not selected the 242 // active background is drawn at |GetThrobValue()|%. This is used for hover, 243 // mini tab title change and pulsing. 244 double GetThrobValue(); 245 246 // Set the temporary offset for the favicon. This is used during the crash 247 // animation. 248 void SetFaviconHidingOffset(int offset); 249 250 void DisplayCrashedFavicon(); 251 void ResetCrashedFavicon(); 252 253 void StopCrashAnimation(); 254 void StartCrashAnimation(); 255 256 // Returns true if the crash animation is currently running. 257 bool IsPerformingCrashAnimation() const; 258 259 // Starts the media indicator fade-in/out animation. There's no stop method 260 // because this is not a continuous animation. 261 void StartMediaIndicatorAnimation(); 262 263 // Schedules repaint task for icon. 264 void ScheduleIconPaint(); 265 266 // Returns the rectangle for the light bar in immersive mode. 267 gfx::Rect GetImmersiveBarRect() const; 268 269 // Gets the tab id and frame id. 270 void GetTabIdAndFrameId(views::Widget* widget, 271 int* tab_id, 272 int* frame_id) const; 273 274 // Performs a one-time initialization of static resources such as tab images. 275 static void InitTabResources(); 276 277 // Returns the minimum possible size of a single unselected Tab, not 278 // including considering touch mode. 279 static gfx::Size GetBasicMinimumUnselectedSize(); 280 281 // Loads the images to be used for the tab background. 282 static void LoadTabImages(); 283 284 // Returns the cached image for the specified arguments, or an empty image if 285 // there isn't one cached. 286 static gfx::ImageSkia GetCachedImage(int resource_id, 287 const gfx::Size& size, 288 ui::ScaleFactor scale_factor); 289 290 // Caches the specified image. 291 static void SetCachedImage(int resource_id, 292 ui::ScaleFactor scale_factor, 293 const gfx::ImageSkia& image); 294 295 // The controller. 296 // WARNING: this is null during detached tab dragging. 297 TabController* controller_; 298 299 TabRendererData data_; 300 301 // True if the tab is being animated closed. 302 bool closing_; 303 304 // True if the tab is being dragged. 305 bool dragging_; 306 307 // The offset used to animate the favicon location. This is used when the tab 308 // crashes. 309 int favicon_hiding_offset_; 310 311 // The current index of the loading animation. The range varies depending on 312 // whether the tab is loading or waiting, see AdvanceLoadingAnimation(). 313 int loading_animation_frame_; 314 315 // Step in the immersive loading progress indicator. 316 int immersive_loading_step_; 317 318 bool should_display_crashed_favicon_; 319 320 // Whole-tab throbbing "pulse" animation. 321 scoped_ptr<gfx::Animation> tab_animation_; 322 323 // Crash icon animation (in place of favicon). 324 scoped_ptr<gfx::LinearAnimation> crash_icon_animation_; 325 326 // Media indicator fade-in/out animation (i.e., only on show/hide, not a 327 // continuous animation). 328 scoped_ptr<gfx::Animation> media_indicator_animation_; 329 TabMediaState animating_media_state_; 330 331 scoped_refptr<gfx::AnimationContainer> animation_container_; 332 333 views::ImageButton* close_button_; 334 335 ui::ThemeProvider* theme_provider_; 336 337 bool tab_activated_with_last_gesture_begin_; 338 339 views::GlowHoverController hover_controller_; 340 341 // The bounds of various sections of the display. 342 gfx::Rect favicon_bounds_; 343 gfx::Rect title_bounds_; 344 gfx::Rect media_indicator_bounds_; 345 346 // The offset used to paint the inactive background image. 347 gfx::Point background_offset_; 348 349 struct TabImage { 350 gfx::ImageSkia* image_l; 351 gfx::ImageSkia* image_c; 352 gfx::ImageSkia* image_r; 353 int l_width; 354 int r_width; 355 }; 356 static TabImage tab_active_; 357 static TabImage tab_inactive_; 358 static TabImage tab_alpha_; 359 360 // Whether we're showing the icon. It is cached so that we can detect when it 361 // changes and layout appropriately. 362 bool showing_icon_; 363 364 // Whether we're showing the media indicator. It is cached so that we can 365 // detect when it changes and layout appropriately. 366 bool showing_media_indicator_; 367 368 // Whether we are showing the close button. It is cached so that we can 369 // detect when it changes and layout appropriately. 370 bool showing_close_button_; 371 372 // The current color of the close button. 373 SkColor close_button_color_; 374 375 static gfx::Font* font_; 376 static int font_height_; 377 378 // As the majority of the tabs are inactive, and painting tabs is slowish, 379 // we cache a handful of the inactive tab backgrounds here. 380 static ImageCache* image_cache_; 381 382 DISALLOW_COPY_AND_ASSIGN(Tab); 383}; 384 385#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_H_ 386