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