- add sources.
[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, either in a TabStrip or in a DraggedTabView.
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   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
134   friend class TabStripTest;
135   FRIEND_TEST_ALL_PREFIXES(TabStripTest, TabHitTestMaskWhenStacked);
136
137   // The animation object used to swap the favicon with the sad tab icon.
138   class FaviconCrashAnimation;
139   class TabCloseButton;
140
141   // Contains a cached image and the values used to generate it.
142   struct ImageCacheEntry {
143     ImageCacheEntry();
144     ~ImageCacheEntry();
145
146     // ID of the resource used.
147     int resource_id;
148
149     // Scale factor we're drawing it.
150     ui::ScaleFactor scale_factor;
151
152     // The image.
153     gfx::ImageSkia image;
154   };
155
156   typedef std::list<ImageCacheEntry> ImageCache;
157
158   // Overridden from gfx::AnimationDelegate:
159   virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
160   virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE;
161   virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
162
163   // Overridden from views::ButtonListener:
164   virtual void ButtonPressed(views::Button* sender,
165                              const ui::Event& event) OVERRIDE;
166
167   // Overridden from views::ContextMenuController:
168   virtual void ShowContextMenuForView(views::View* source,
169                                       const gfx::Point& point,
170                                       ui::MenuSourceType source_type) OVERRIDE;
171
172   // Overridden from views::View:
173   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
174   virtual void Layout() OVERRIDE;
175   virtual void OnThemeChanged() OVERRIDE;
176   virtual const char* GetClassName() const OVERRIDE;
177   virtual bool HasHitTestMask() const OVERRIDE;
178   virtual void GetHitTestMask(HitTestSource source,
179                               gfx::Path* path) const OVERRIDE;
180   virtual bool GetTooltipText(const gfx::Point& p,
181                               string16* tooltip) const OVERRIDE;
182   virtual bool GetTooltipTextOrigin(const gfx::Point& p,
183                                     gfx::Point* origin) const OVERRIDE;
184   virtual ui::ThemeProvider* GetThemeProvider() const OVERRIDE;
185   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
186   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
187   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
188   virtual void OnMouseCaptureLost() OVERRIDE;
189   virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
190   virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE;
191   virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
192   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
193
194   // Overridden from ui::EventHandler:
195   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
196
197   // Returns the bounds of the title and icon.
198   const gfx::Rect& GetTitleBounds() const;
199   const gfx::Rect& GetIconBounds() const;
200
201   // Invoked from Layout to adjust the position of the favicon or media
202   // indicator for mini tabs.
203   void MaybeAdjustLeftForMiniTab(gfx::Rect* bounds) const;
204
205   // Invoked from SetData after |data_| has been updated to the new data.
206   void DataChanged(const TabRendererData& old);
207
208   // Paint with the normal tab style.
209   void PaintTab(gfx::Canvas* canvas);
210
211   // Paint with the "immersive mode" light-bar style.
212   void PaintImmersiveTab(gfx::Canvas* canvas);
213
214   // Paint various portions of the Tab
215   void PaintTabBackground(gfx::Canvas* canvas);
216   void PaintInactiveTabBackgroundWithTitleChange(
217       gfx::Canvas* canvas,
218       gfx::MultiAnimation* animation);
219   void PaintInactiveTabBackground(gfx::Canvas* canvas);
220   void PaintInactiveTabBackgroundUsingResourceId(gfx::Canvas* canvas,
221                                                  int tab_id);
222   void PaintActiveTabBackground(gfx::Canvas* canvas);
223
224   // Paints the favicon, media indicator icon, etc., mirrored for RTL if needed.
225   void PaintIcon(gfx::Canvas* canvas);
226   void PaintMediaIndicator(gfx::Canvas* canvas);
227   void PaintTitle(gfx::Canvas* canvas, SkColor title_color);
228
229   // Invoked if data_.network_state changes, or the network_state is not none.
230   void AdvanceLoadingAnimation(TabRendererData::NetworkState old_state,
231                                TabRendererData::NetworkState state);
232
233   // Returns the number of favicon-size elements that can fit in the tab's
234   // current size.
235   int IconCapacity() const;
236
237   // Returns whether the Tab should display a favicon.
238   bool ShouldShowIcon() const;
239
240   // Returns whether the Tab should display the media indicator.
241   bool ShouldShowMediaIndicator() const;
242
243   // Returns whether the Tab should display a close button.
244   bool ShouldShowCloseBox() const;
245
246   // Gets the throb value for the tab. When a tab is not selected the
247   // active background is drawn at |GetThrobValue()|%. This is used for hover,
248   // mini tab title change and pulsing.
249   double GetThrobValue();
250
251   // Set the temporary offset for the favicon. This is used during the crash
252   // animation.
253   void SetFaviconHidingOffset(int offset);
254
255   void DisplayCrashedFavicon();
256   void ResetCrashedFavicon();
257
258   void StopCrashAnimation();
259   void StartCrashAnimation();
260
261   // Returns true if the crash animation is currently running.
262   bool IsPerformingCrashAnimation() const;
263
264   // Starts the media indicator fade-in/out animation. There's no stop method
265   // because this is not a continuous animation.
266   void StartMediaIndicatorAnimation();
267
268   // Schedules repaint task for icon.
269   void ScheduleIconPaint();
270
271   // Returns the rectangle for the light bar in immersive mode.
272   gfx::Rect GetImmersiveBarRect() const;
273
274   // Gets the tab id and frame id.
275   void GetTabIdAndFrameId(views::Widget* widget,
276                           int* tab_id,
277                           int* frame_id) const;
278
279   // Performs a one-time initialization of static resources such as tab images.
280   static void InitTabResources();
281
282   // Returns the minimum possible size of a single unselected Tab, not
283   // including considering touch mode.
284   static gfx::Size GetBasicMinimumUnselectedSize();
285
286   // Loads the images to be used for the tab background.
287   static void LoadTabImages();
288
289   // Returns the cached image for the specified arguments, or an empty image if
290   // there isn't one cached.
291   static gfx::ImageSkia GetCachedImage(int resource_id,
292                                        const gfx::Size& size,
293                                        ui::ScaleFactor scale_factor);
294
295   // Caches the specified image.
296   static void SetCachedImage(int resource_id,
297                              ui::ScaleFactor scale_factor,
298                              const gfx::ImageSkia& image);
299
300   // The controller.
301   // WARNING: this is null during detached tab dragging.
302   TabController* controller_;
303
304   TabRendererData data_;
305
306   // True if the tab is being animated closed.
307   bool closing_;
308
309   // True if the tab is being dragged.
310   bool dragging_;
311
312   // The offset used to animate the favicon location. This is used when the tab
313   // crashes.
314   int favicon_hiding_offset_;
315
316   // The current index of the loading animation. The range varies depending on
317   // whether the tab is loading or waiting, see AdvanceLoadingAnimation().
318   int loading_animation_frame_;
319
320   // Step in the immersive loading progress indicator.
321   int immersive_loading_step_;
322
323   bool should_display_crashed_favicon_;
324
325   // Whole-tab throbbing "pulse" animation.
326   scoped_ptr<gfx::Animation> tab_animation_;
327
328   // Crash icon animation (in place of favicon).
329   scoped_ptr<gfx::LinearAnimation> crash_icon_animation_;
330
331   // Media indicator fade-in/out animation (i.e., only on show/hide, not a
332   // continuous animation).
333   scoped_ptr<gfx::Animation> media_indicator_animation_;
334   TabMediaState animating_media_state_;
335
336   scoped_refptr<gfx::AnimationContainer> animation_container_;
337
338   views::ImageButton* close_button_;
339
340   ui::ThemeProvider* theme_provider_;
341
342   bool tab_activated_with_last_gesture_begin_;
343
344   views::GlowHoverController hover_controller_;
345
346   // The bounds of various sections of the display.
347   gfx::Rect favicon_bounds_;
348   gfx::Rect title_bounds_;
349   gfx::Rect media_indicator_bounds_;
350
351   // The offset used to paint the inactive background image.
352   gfx::Point background_offset_;
353
354   struct TabImage {
355     gfx::ImageSkia* image_l;
356     gfx::ImageSkia* image_c;
357     gfx::ImageSkia* image_r;
358     int l_width;
359     int r_width;
360   };
361   static TabImage tab_active_;
362   static TabImage tab_inactive_;
363   static TabImage tab_alpha_;
364
365   // Whether we're showing the icon. It is cached so that we can detect when it
366   // changes and layout appropriately.
367   bool showing_icon_;
368
369   // Whether we're showing the media indicator. It is cached so that we can
370   // detect when it changes and layout appropriately.
371   bool showing_media_indicator_;
372
373   // Whether we are showing the close button. It is cached so that we can
374   // detect when it changes and layout appropriately.
375   bool showing_close_button_;
376
377   // The current color of the close button.
378   SkColor close_button_color_;
379
380   static gfx::Font* font_;
381   static int font_height_;
382
383   // As the majority of the tabs are inactive, and painting tabs is slowish,
384   // we cache a handful of the inactive tab backgrounds here.
385   static ImageCache* image_cache_;
386
387   DISALLOW_COPY_AND_ASSIGN(Tab);
388 };
389
390 #endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_H_