Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / tabs / tab.h
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
22 class TabController;
23
24 namespace gfx {
25 class Animation;
26 class AnimationContainer;
27 class Font;
28 class LinearAnimation;
29 class MultiAnimation;
30 }
31 namespace views {
32 class ImageButton;
33 }
34
35 ///////////////////////////////////////////////////////////////////////////////
36 //
37 //  A View that renders a Tab in a TabStrip.
38 //
39 ///////////////////////////////////////////////////////////////////////////////
40 class 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::AccessibleViewState* 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_