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