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.
5 #ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_H_
6 #define CHROME_BROWSER_UI_VIEWS_TABS_TAB_H_
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"
26 class AnimationContainer
;
28 class LinearAnimation
;
35 ///////////////////////////////////////////////////////////////////////////////
37 // A View that renders a Tab in a TabStrip.
39 ///////////////////////////////////////////////////////////////////////////////
40 class Tab
: public gfx::AnimationDelegate
,
41 public views::ButtonListener
,
42 public views::ContextMenuController
,
45 // The menu button's class name.
46 static const char kViewClassName
[];
48 explicit Tab(TabController
* controller
);
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_
; }
55 // See description above field.
56 void set_dragging(bool dragging
) { dragging_
= dragging
; }
57 bool dragging() const { return dragging_
; }
59 // Sets the container all animations run from.
60 void set_animation_container(gfx::AnimationContainer
* container
);
62 // Returns true if this tab is the active tab.
63 bool IsActive() const;
65 // Returns true if the tab is selected.
66 bool IsSelected() const;
68 // Sets the data this tabs displays. Invokes DataChanged.
69 void SetData(const TabRendererData
& data
);
70 const TabRendererData
& data() const { return data_
; }
72 // Sets the network state. If the network state changes NetworkStateChanged is
74 void UpdateLoadingAnimation(TabRendererData::NetworkState state
);
76 // Starts/Stops a pulse animation.
80 // Start/stop the mini-tab title animation.
81 void StartMiniTabTitleAnimation();
82 void StopMiniTabTitleAnimation();
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
;
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_
;
98 views::GlowHoverController
* hover_controller() {
99 return &hover_controller_
;
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
107 static gfx::Size
GetMinimumSelectedSize();
108 // Returns the preferred size of a single Tab, assuming space is
110 static gfx::Size
GetStandardSize();
112 // Returns the width for touch tabs.
113 static int GetTouchWidth();
115 // Returns the width for mini-tabs. Mini-tabs always have this width.
116 static int GetMiniWidth();
118 // Returns the height for immersive mode tabs.
119 static int GetImmersiveHeight();
122 friend class TabTest
;
123 FRIEND_TEST_ALL_PREFIXES(TabTest
, CloseButtonLayout
);
125 friend class TabStripTest
;
126 FRIEND_TEST_ALL_PREFIXES(TabStripTest
, TabHitTestMaskWhenStacked
);
127 FRIEND_TEST_ALL_PREFIXES(TabStripTest
, ClippedTabCloseButton
);
129 // The animation object used to swap the favicon with the sad tab icon.
130 class FaviconCrashAnimation
;
131 class TabCloseButton
;
133 // Contains a cached image and the values used to generate it.
134 struct ImageCacheEntry
{
138 // ID of the resource used.
141 // Scale factor we're drawing it.
142 ui::ScaleFactor scale_factor
;
145 gfx::ImageSkia image
;
148 typedef std::list
<ImageCacheEntry
> ImageCache
;
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
;
155 // Overridden from views::ButtonListener:
156 virtual void ButtonPressed(views::Button
* sender
,
157 const ui::Event
& event
) OVERRIDE
;
159 // Overridden from views::ContextMenuController:
160 virtual void ShowContextMenuForView(views::View
* source
,
161 const gfx::Point
& point
,
162 ui::MenuSourceType source_type
) OVERRIDE
;
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
;
185 // Overridden from ui::EventHandler:
186 virtual void OnGestureEvent(ui::GestureEvent
* event
) OVERRIDE
;
188 // Returns the bounds of the title and icon.
189 const gfx::Rect
& GetTitleBounds() const;
190 const gfx::Rect
& GetIconBounds() const;
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;
196 // Invoked from SetData after |data_| has been updated to the new data.
197 void DataChanged(const TabRendererData
& old
);
199 // Paint with the normal tab style.
200 void PaintTab(gfx::Canvas
* canvas
);
202 // Paint with the "immersive mode" light-bar style.
203 void PaintImmersiveTab(gfx::Canvas
* canvas
);
205 // Paint various portions of the Tab
206 void PaintTabBackground(gfx::Canvas
* canvas
);
207 void PaintInactiveTabBackgroundWithTitleChange(
209 gfx::MultiAnimation
* animation
);
210 void PaintInactiveTabBackground(gfx::Canvas
* canvas
);
211 void PaintInactiveTabBackgroundUsingResourceId(gfx::Canvas
* canvas
,
213 void PaintActiveTabBackground(gfx::Canvas
* canvas
);
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
);
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
);
224 // Returns the number of favicon-size elements that can fit in the tab's
226 int IconCapacity() const;
228 // Returns whether the Tab should display a favicon.
229 bool ShouldShowIcon() const;
231 // Returns whether the Tab should display the media indicator.
232 bool ShouldShowMediaIndicator() const;
234 // Returns whether the Tab should display a close button.
235 bool ShouldShowCloseBox() const;
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();
242 // Set the temporary offset for the favicon. This is used during the crash
244 void SetFaviconHidingOffset(int offset
);
246 void DisplayCrashedFavicon();
247 void ResetCrashedFavicon();
249 void StopCrashAnimation();
250 void StartCrashAnimation();
252 // Returns true if the crash animation is currently running.
253 bool IsPerformingCrashAnimation() const;
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();
259 // Schedules repaint task for icon.
260 void ScheduleIconPaint();
262 // Returns the rectangle for the light bar in immersive mode.
263 gfx::Rect
GetImmersiveBarRect() const;
265 // Gets the tab id and frame id.
266 void GetTabIdAndFrameId(views::Widget
* widget
,
268 int* frame_id
) const;
270 // Performs a one-time initialization of static resources such as tab images.
271 static void InitTabResources();
273 // Returns the minimum possible size of a single unselected Tab, not
274 // including considering touch mode.
275 static gfx::Size
GetBasicMinimumUnselectedSize();
277 // Loads the images to be used for the tab background.
278 static void LoadTabImages();
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
);
286 // Caches the specified image.
287 static void SetCachedImage(int resource_id
,
288 ui::ScaleFactor scale_factor
,
289 const gfx::ImageSkia
& image
);
291 // The controller, never NULL.
292 TabController
* controller_
;
294 TabRendererData data_
;
296 // True if the tab is being animated closed.
299 // True if the tab is being dragged.
302 // The offset used to animate the favicon location. This is used when the tab
304 int favicon_hiding_offset_
;
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_
;
310 // Step in the immersive loading progress indicator.
311 int immersive_loading_step_
;
313 bool should_display_crashed_favicon_
;
315 // Whole-tab throbbing "pulse" animation.
316 scoped_ptr
<gfx::Animation
> tab_animation_
;
318 // Crash icon animation (in place of favicon).
319 scoped_ptr
<gfx::LinearAnimation
> crash_icon_animation_
;
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_
;
326 scoped_refptr
<gfx::AnimationContainer
> animation_container_
;
328 views::ImageButton
* close_button_
;
330 bool tab_activated_with_last_gesture_begin_
;
332 views::GlowHoverController hover_controller_
;
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_
;
339 // The offset used to paint the inactive background image.
340 gfx::Point background_offset_
;
343 gfx::ImageSkia
* image_l
;
344 gfx::ImageSkia
* image_c
;
345 gfx::ImageSkia
* image_r
;
349 static TabImage tab_active_
;
350 static TabImage tab_inactive_
;
351 static TabImage tab_alpha_
;
353 // Whether we're showing the icon. It is cached so that we can detect when it
354 // changes and layout appropriately.
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_
;
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_
;
365 // The current color of the close button.
366 SkColor close_button_color_
;
368 static gfx::Font
* font_
;
369 static int font_height_
;
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_
;
375 DISALLOW_COPY_AND_ASSIGN(Tab
);
378 #endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_H_