Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: chrome/browser/views/tabs/base_tab.cc

Issue 2863003: Attempt 2 at: (Closed)
Patch Set: Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/views/tabs/base_tab.h ('k') | chrome/browser/views/tabs/side_tab.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/views/tabs/base_tab.h" 5 #include "chrome/browser/views/tabs/base_tab.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "app/animation_container.h" 9 #include "app/animation_container.h"
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
11 #include "app/resource_bundle.h" 11 #include "app/resource_bundle.h"
12 #include "app/slide_animation.h" 12 #include "app/slide_animation.h"
13 #include "app/throb_animation.h" 13 #include "app/throb_animation.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/browser.h" 16 #include "chrome/browser/browser.h"
17 #include "chrome/browser/tab_contents/tab_contents.h" 17 #include "chrome/browser/tab_contents/tab_contents.h"
18 #include "chrome/browser/views/tabs/tab_controller.h" 18 #include "chrome/browser/views/tabs/tab_controller.h"
19 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
20 #include "gfx/canvas.h" 20 #include "gfx/canvas.h"
21 #include "gfx/favicon_size.h" 21 #include "gfx/favicon_size.h"
22 #include "gfx/font.h" 22 #include "gfx/font.h"
23 #include "gfx/skbitmap_operations.h"
23 #include "grit/app_resources.h" 24 #include "grit/app_resources.h"
24 #include "grit/generated_resources.h" 25 #include "grit/generated_resources.h"
25 #include "grit/theme_resources.h" 26 #include "grit/theme_resources.h"
26 #include "views/controls/button/image_button.h" 27 #include "views/controls/button/image_button.h"
27 28
28 #ifdef WIN32 29 #ifdef WIN32
29 #include "app/win_util.h" 30 #include "app/win_util.h"
30 #endif 31 #endif
31 32
32 // How long the pulse throb takes. 33 // How long the pulse throb takes.
33 static const int kPulseDurationMs = 200; 34 static const int kPulseDurationMs = 200;
34 35
35 // How long the hover state takes. 36 // How long the hover state takes.
36 static const int kHoverDurationMs = 90; 37 static const int kHoverDurationMs = 90;
37 38
38 static SkBitmap* waiting_animation_frames = NULL; 39 static SkBitmap* waiting_animation_frames = NULL;
39 static SkBitmap* loading_animation_frames = NULL; 40 static SkBitmap* loading_animation_frames = NULL;
40 static int loading_animation_frame_count = 0; 41 static int loading_animation_frame_count = 0;
41 static int waiting_animation_frame_count = 0; 42 static int waiting_animation_frame_count = 0;
42 static int waiting_to_loading_frame_count_ratio = 0; 43 static int waiting_to_loading_frame_count_ratio = 0;
43 44
44 // Close button images. 45 // Close button images.
45 static SkBitmap* close_button_n = NULL; 46 static SkBitmap* close_button_n = NULL;
46 static SkBitmap* close_button_h = NULL; 47 static SkBitmap* close_button_h = NULL;
47 static SkBitmap* close_button_p = NULL; 48 static SkBitmap* close_button_p = NULL;
48 49
49 static SkBitmap* crashed_fav_icon = NULL; 50 static SkBitmap* crashed_fav_icon = NULL;
50 51
51 namespace {
52
53 //////////////////////////////////////////////////////////////////////////////// 52 ////////////////////////////////////////////////////////////////////////////////
54 // TabCloseButton 53 // TabCloseButton
55 // 54 //
56 // This is a Button subclass that causes middle clicks to be forwarded to the 55 // This is a Button subclass that causes middle clicks to be forwarded to the
57 // parent View by explicitly not handling them in OnMousePressed. 56 // parent View by explicitly not handling them in OnMousePressed.
58 class TabCloseButton : public views::ImageButton { 57 class BaseTab::TabCloseButton : public views::ImageButton {
59 public: 58 public:
60 explicit TabCloseButton(views::ButtonListener* listener) 59 TabCloseButton(BaseTab* tab, bool show_mini_dot)
61 : views::ImageButton(listener) { 60 : views::ImageButton(tab),
61 tab_(tab),
62 is_mouse_near_(!show_mini_dot),
63 color_(0) {
62 } 64 }
63 virtual ~TabCloseButton() {} 65 virtual ~TabCloseButton() {}
64 66
67 // Sets the color used to derive the background color.
68 void SetColor(SkColor color) {
69 if (color_ == color)
70 return;
71
72 color_ = color;
73 // This is invoked from Paint, so we don't need to schedule a paint.
74 UpdateBackgroundImage(false);
75 }
76
77 // Invoked when the selected state changes.
78 void SelectedStateChanged() {
79 UpdateBackgroundImage(true);
80 }
81
65 virtual bool OnMousePressed(const views::MouseEvent& event) { 82 virtual bool OnMousePressed(const views::MouseEvent& event) {
66 bool handled = ImageButton::OnMousePressed(event); 83 bool handled = ImageButton::OnMousePressed(event);
67 // Explicitly mark midle-mouse clicks as non-handled to ensure the tab 84 // Explicitly mark midle-mouse clicks as non-handled to ensure the tab
68 // sees them. 85 // sees them.
69 return event.IsOnlyMiddleMouseButton() ? false : handled; 86 return event.IsOnlyMiddleMouseButton() ? false : handled;
70 } 87 }
71 88
72 // We need to let the parent know about mouse state so that it 89 // We need to let the parent know about mouse state so that it
73 // can highlight itself appropriately. Note that Exit events 90 // can highlight itself appropriately. Note that Exit events
74 // fire before Enter events, so this works. 91 // fire before Enter events, so this works.
75 virtual void OnMouseEntered(const views::MouseEvent& event) { 92 virtual void OnMouseEntered(const views::MouseEvent& event) {
76 CustomButton::OnMouseEntered(event); 93 CustomButton::OnMouseEntered(event);
77 GetParent()->OnMouseEntered(event); 94 GetParent()->OnMouseEntered(event);
78 } 95 }
79 96
80 virtual void OnMouseExited(const views::MouseEvent& event) { 97 virtual void OnMouseExited(const views::MouseEvent& event) {
81 CustomButton::OnMouseExited(event); 98 CustomButton::OnMouseExited(event);
82 GetParent()->OnMouseExited(event); 99 GetParent()->OnMouseExited(event);
83 } 100 }
84 101
102 virtual void OnMouseNear(const views::MouseEvent& event) {
103 is_mouse_near_ = true;
104 UpdateBackgroundImage(true);
105 }
106
107 virtual void OnMouseExitedNear(const views::MouseEvent& event) {
108 is_mouse_near_ = false;
109 UpdateBackgroundImage(true);
110 }
111
85 private: 112 private:
113 // Returns the image to use for the background.
114 static const SkBitmap& GetBackgroundImage(SkColor color, bool is_mouse_near) {
115 // All tabs share the same color, so we cache the bitmaps.
116 static SkColor cached_color = 0;
117 static SkBitmap* near_image = NULL;
118 static SkBitmap* far_image = NULL;
119 if (!near_image || cached_color != color) {
120 cached_color = color;
121 if (!near_image) {
122 near_image = new SkBitmap();
123 far_image = new SkBitmap();
124 }
125 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
126 *near_image = SkBitmapOperations::CreateButtonBackground(
127 color,
128 *rb.GetBitmapNamed(IDR_TAB_CLOSE),
129 *rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK));
130 *far_image = SkBitmapOperations::CreateButtonBackground(
131 color,
132 *rb.GetBitmapNamed(IDR_TAB_CLOSE),
133 *rb.GetBitmapNamed(IDR_TAB_CLOSE_DOT_MASK));
134 }
135 return is_mouse_near ? *near_image : *far_image;
136 }
137
138 // Should we use the near image?
139 bool use_near_image() const { return is_mouse_near_ || tab_->IsSelected(); }
140
141 // Resets the background image.
142 void UpdateBackgroundImage(bool paint) {
143 set_background_image(GetBackgroundImage(color_, use_near_image()));
144 if (paint)
145 SchedulePaint();
146 }
147
148 BaseTab* tab_;
149
150 // Is the mouse near the close button?
151 bool is_mouse_near_;
152
153 // Color used to derive the background image from.
154 SkColor color_;
155
86 DISALLOW_COPY_AND_ASSIGN(TabCloseButton); 156 DISALLOW_COPY_AND_ASSIGN(TabCloseButton);
87 }; 157 };
88 158
89 } // namespace
90
91 // static 159 // static
92 int BaseTab::close_button_width_ = 0; 160 int BaseTab::close_button_width_ = 0;
93 // static 161 // static
94 int BaseTab::close_button_height_ = 0; 162 int BaseTab::close_button_height_ = 0;
95 // static 163 // static
96 int BaseTab::loading_animation_size_ = 0; 164 int BaseTab::loading_animation_size_ = 0;
97 165
98 // static 166 // static
99 gfx::Font* BaseTab::font_ = NULL; 167 gfx::Font* BaseTab::font_ = NULL;
100 // static 168 // static
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 virtual void AnimationCanceled(const Animation* animation) { 200 virtual void AnimationCanceled(const Animation* animation) {
133 target_->SetFavIconHidingOffset(0); 201 target_->SetFavIconHidingOffset(0);
134 } 202 }
135 203
136 private: 204 private:
137 BaseTab* target_; 205 BaseTab* target_;
138 206
139 DISALLOW_COPY_AND_ASSIGN(FavIconCrashAnimation); 207 DISALLOW_COPY_AND_ASSIGN(FavIconCrashAnimation);
140 }; 208 };
141 209
142 BaseTab::BaseTab(TabController* controller) 210 BaseTab::BaseTab(TabController* controller, bool show_mini_dot)
143 : controller_(controller), 211 : controller_(controller),
144 closing_(false), 212 closing_(false),
145 dragging_(false), 213 dragging_(false),
146 loading_animation_frame_(0), 214 loading_animation_frame_(0),
147 throbber_disabled_(false), 215 throbber_disabled_(false),
148 theme_provider_(NULL), 216 theme_provider_(NULL),
149 fav_icon_hiding_offset_(0), 217 fav_icon_hiding_offset_(0),
150 should_display_crashed_favicon_(false) { 218 should_display_crashed_favicon_(false) {
151 BaseTab::InitResources(); 219 BaseTab::InitResources();
152 220
153 // Add the Close Button. 221 // Add the Close Button.
154 TabCloseButton* close_button = new TabCloseButton(this); 222 TabCloseButton* close_button = new TabCloseButton(this, show_mini_dot);
155 close_button_ = close_button; 223 close_button_ = close_button;
156 close_button->SetImage(views::CustomButton::BS_NORMAL, close_button_n); 224 close_button->SetImage(views::CustomButton::BS_NORMAL, close_button_n);
157 close_button->SetImage(views::CustomButton::BS_HOT, close_button_h); 225 close_button->SetImage(views::CustomButton::BS_HOT, close_button_h);
158 close_button->SetImage(views::CustomButton::BS_PUSHED, close_button_p); 226 close_button->SetImage(views::CustomButton::BS_PUSHED, close_button_p);
159 close_button->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_CLOSE_TAB)); 227 close_button->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_CLOSE_TAB));
160 close_button->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); 228 close_button->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE));
161 close_button->SetAnimationDuration(0); 229 close_button->SetAnimationDuration(0);
162 AddChildView(close_button); 230 AddChildView(close_button);
163 231
164 SetContextMenuController(this); 232 SetContextMenuController(this);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 } 289 }
222 290
223 void BaseTab::StopPulse() { 291 void BaseTab::StopPulse() {
224 if (!pulse_animation_.get()) 292 if (!pulse_animation_.get())
225 return; 293 return;
226 294
227 pulse_animation_->Stop(); // Do stop so we get notified. 295 pulse_animation_->Stop(); // Do stop so we get notified.
228 pulse_animation_.reset(NULL); 296 pulse_animation_.reset(NULL);
229 } 297 }
230 298
299 void BaseTab::SelectedChanged() {
300 close_button_->SelectedStateChanged();
301 }
302
231 bool BaseTab::IsSelected() const { 303 bool BaseTab::IsSelected() const {
232 return controller() ? controller()->IsTabSelected(this) : true; 304 return controller() ? controller()->IsTabSelected(this) : true;
233 } 305 }
234 306
235 void BaseTab::OnMouseEntered(const views::MouseEvent& e) { 307 void BaseTab::OnMouseEntered(const views::MouseEvent& e) {
236 if (!hover_animation_.get()) { 308 if (!hover_animation_.get()) {
237 hover_animation_.reset(new SlideAnimation(this)); 309 hover_animation_.reset(new SlideAnimation(this));
238 hover_animation_->SetContainer(animation_container_.get()); 310 hover_animation_->SetContainer(animation_container_.get());
239 hover_animation_->SetSlideDuration(kHoverDurationMs); 311 hover_animation_->SetSlideDuration(kHoverDurationMs);
240 } 312 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 if (state != TabRendererData::NETWORK_STATE_NONE) { 399 if (state != TabRendererData::NETWORK_STATE_NONE) {
328 loading_animation_frame_ = ++loading_animation_frame_ % 400 loading_animation_frame_ = ++loading_animation_frame_ %
329 ((state == TabRendererData::NETWORK_STATE_WAITING) ? 401 ((state == TabRendererData::NETWORK_STATE_WAITING) ?
330 waiting_animation_frame_count : loading_animation_frame_count); 402 waiting_animation_frame_count : loading_animation_frame_count);
331 } else { 403 } else {
332 loading_animation_frame_ = 0; 404 loading_animation_frame_ = 0;
333 } 405 }
334 SchedulePaint(); 406 SchedulePaint();
335 } 407 }
336 408
409 views::ImageButton* BaseTab::close_button() const {
410 return close_button_;
411 }
412
413 void BaseTab::SetCloseButtonColor(SkColor color) {
414 close_button_->SetColor(color);
415 }
416
337 void BaseTab::PaintIcon(gfx::Canvas* canvas, int x, int y) { 417 void BaseTab::PaintIcon(gfx::Canvas* canvas, int x, int y) {
338 if (base::i18n::IsRTL()) { 418 if (base::i18n::IsRTL()) {
339 if (!data().favicon.isNull()) 419 if (!data().favicon.isNull())
340 x = width() - x - data().favicon.width(); 420 x = width() - x - data().favicon.width();
341 else 421 else
342 x = width() - x - kFavIconSize; 422 x = width() - x - kFavIconSize;
343 } 423 }
344 424
345 int favicon_x = x; 425 int favicon_x = x;
346 if (!data().favicon.isNull() && data().favicon.width() != kFavIconSize) 426 if (!data().favicon.isNull() && data().favicon.width() != kFavIconSize)
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 font_height_ = font_->height(); 609 font_height_ = font_->height();
530 } 610 }
531 611
532 // static 612 // static
533 void BaseTab::LoadThemeImages() { 613 void BaseTab::LoadThemeImages() {
534 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 614 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
535 loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER); 615 loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER);
536 waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING); 616 waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING);
537 loading_animation_size_ = loading_animation_frames->height(); 617 loading_animation_size_ = loading_animation_frames->height();
538 } 618 }
OLDNEW
« no previous file with comments | « chrome/browser/views/tabs/base_tab.h ('k') | chrome/browser/views/tabs/side_tab.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698