OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/ui/views/tabs/tab.h" | 5 #include "chrome/browser/ui/views/tabs/tab.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 // FaviconCrashAnimation | 192 // FaviconCrashAnimation |
193 // | 193 // |
194 // A custom animation subclass to manage the favicon crash animation. | 194 // A custom animation subclass to manage the favicon crash animation. |
195 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, | 195 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, |
196 public gfx::AnimationDelegate { | 196 public gfx::AnimationDelegate { |
197 public: | 197 public: |
198 explicit FaviconCrashAnimation(Tab* target) | 198 explicit FaviconCrashAnimation(Tab* target) |
199 : gfx::LinearAnimation(1000, 25, this), | 199 : gfx::LinearAnimation(1000, 25, this), |
200 target_(target) { | 200 target_(target) { |
201 } | 201 } |
202 virtual ~FaviconCrashAnimation() {} | 202 ~FaviconCrashAnimation() override {} |
203 | 203 |
204 // gfx::Animation overrides: | 204 // gfx::Animation overrides: |
205 virtual void AnimateToState(double state) override { | 205 void AnimateToState(double state) override { |
206 const double kHidingOffset = 27; | 206 const double kHidingOffset = 27; |
207 | 207 |
208 if (state < .5) { | 208 if (state < .5) { |
209 target_->SetFaviconHidingOffset( | 209 target_->SetFaviconHidingOffset( |
210 static_cast<int>(floor(kHidingOffset * 2.0 * state))); | 210 static_cast<int>(floor(kHidingOffset * 2.0 * state))); |
211 } else { | 211 } else { |
212 target_->DisplayCrashedFavicon(); | 212 target_->DisplayCrashedFavicon(); |
213 target_->SetFaviconHidingOffset( | 213 target_->SetFaviconHidingOffset( |
214 static_cast<int>( | 214 static_cast<int>( |
215 floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset)))); | 215 floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset)))); |
216 } | 216 } |
217 } | 217 } |
218 | 218 |
219 // gfx::AnimationDelegate overrides: | 219 // gfx::AnimationDelegate overrides: |
220 virtual void AnimationCanceled(const gfx::Animation* animation) override { | 220 void AnimationCanceled(const gfx::Animation* animation) override { |
221 target_->SetFaviconHidingOffset(0); | 221 target_->SetFaviconHidingOffset(0); |
222 } | 222 } |
223 | 223 |
224 private: | 224 private: |
225 Tab* target_; | 225 Tab* target_; |
226 | 226 |
227 DISALLOW_COPY_AND_ASSIGN(FaviconCrashAnimation); | 227 DISALLOW_COPY_AND_ASSIGN(FaviconCrashAnimation); |
228 }; | 228 }; |
229 | 229 |
230 //////////////////////////////////////////////////////////////////////////////// | 230 //////////////////////////////////////////////////////////////////////////////// |
231 // TabCloseButton | 231 // TabCloseButton |
232 // | 232 // |
233 // This is a Button subclass that causes middle clicks to be forwarded to the | 233 // This is a Button subclass that causes middle clicks to be forwarded to the |
234 // parent View by explicitly not handling them in OnMousePressed. | 234 // parent View by explicitly not handling them in OnMousePressed. |
235 class Tab::TabCloseButton : public views::ImageButton, | 235 class Tab::TabCloseButton : public views::ImageButton, |
236 public views::MaskedTargeterDelegate { | 236 public views::MaskedTargeterDelegate { |
237 public: | 237 public: |
238 explicit TabCloseButton(Tab* tab) | 238 explicit TabCloseButton(Tab* tab) |
239 : views::ImageButton(tab), | 239 : views::ImageButton(tab), |
240 tab_(tab) { | 240 tab_(tab) { |
241 SetEventTargeter( | 241 SetEventTargeter( |
242 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); | 242 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); |
243 } | 243 } |
244 | 244 |
245 virtual ~TabCloseButton() {} | 245 ~TabCloseButton() override {} |
246 | 246 |
247 // views::View: | 247 // views::View: |
248 virtual View* GetTooltipHandlerForPoint(const gfx::Point& point) override { | 248 View* GetTooltipHandlerForPoint(const gfx::Point& point) override { |
249 // Tab close button has no children, so tooltip handler should be the same | 249 // Tab close button has no children, so tooltip handler should be the same |
250 // as the event handler. | 250 // as the event handler. |
251 // In addition, a hit test has to be performed for the point (as | 251 // In addition, a hit test has to be performed for the point (as |
252 // GetTooltipHandlerForPoint() is responsible for it). | 252 // GetTooltipHandlerForPoint() is responsible for it). |
253 if (!HitTestPoint(point)) | 253 if (!HitTestPoint(point)) |
254 return NULL; | 254 return NULL; |
255 return GetEventHandlerForPoint(point); | 255 return GetEventHandlerForPoint(point); |
256 } | 256 } |
257 | 257 |
258 virtual bool OnMousePressed(const ui::MouseEvent& event) override { | 258 bool OnMousePressed(const ui::MouseEvent& event) override { |
259 tab_->controller_->OnMouseEventInTab(this, event); | 259 tab_->controller_->OnMouseEventInTab(this, event); |
260 | 260 |
261 bool handled = ImageButton::OnMousePressed(event); | 261 bool handled = ImageButton::OnMousePressed(event); |
262 // Explicitly mark midle-mouse clicks as non-handled to ensure the tab | 262 // Explicitly mark midle-mouse clicks as non-handled to ensure the tab |
263 // sees them. | 263 // sees them. |
264 return event.IsOnlyMiddleMouseButton() ? false : handled; | 264 return event.IsOnlyMiddleMouseButton() ? false : handled; |
265 } | 265 } |
266 | 266 |
267 virtual void OnMouseMoved(const ui::MouseEvent& event) override { | 267 void OnMouseMoved(const ui::MouseEvent& event) override { |
268 tab_->controller_->OnMouseEventInTab(this, event); | 268 tab_->controller_->OnMouseEventInTab(this, event); |
269 CustomButton::OnMouseMoved(event); | 269 CustomButton::OnMouseMoved(event); |
270 } | 270 } |
271 | 271 |
272 virtual void OnMouseReleased(const ui::MouseEvent& event) override { | 272 void OnMouseReleased(const ui::MouseEvent& event) override { |
273 tab_->controller_->OnMouseEventInTab(this, event); | 273 tab_->controller_->OnMouseEventInTab(this, event); |
274 CustomButton::OnMouseReleased(event); | 274 CustomButton::OnMouseReleased(event); |
275 } | 275 } |
276 | 276 |
277 virtual void OnGestureEvent(ui::GestureEvent* event) override { | 277 void OnGestureEvent(ui::GestureEvent* event) override { |
278 // Consume all gesture events here so that the parent (Tab) does not | 278 // Consume all gesture events here so that the parent (Tab) does not |
279 // start consuming gestures. | 279 // start consuming gestures. |
280 ImageButton::OnGestureEvent(event); | 280 ImageButton::OnGestureEvent(event); |
281 event->SetHandled(); | 281 event->SetHandled(); |
282 } | 282 } |
283 | 283 |
284 virtual const char* GetClassName() const override { | 284 const char* GetClassName() const override { return kTabCloseButtonName; } |
285 return kTabCloseButtonName; | |
286 } | |
287 | 285 |
288 private: | 286 private: |
289 // Returns the rectangular bounds of parent tab's visible region in the | 287 // Returns the rectangular bounds of parent tab's visible region in the |
290 // local coordinate space of |this|. | 288 // local coordinate space of |this|. |
291 gfx::Rect GetTabBounds() const { | 289 gfx::Rect GetTabBounds() const { |
292 gfx::Path tab_mask; | 290 gfx::Path tab_mask; |
293 tab_->GetHitTestMask(&tab_mask); | 291 tab_->GetHitTestMask(&tab_mask); |
294 | 292 |
295 gfx::RectF tab_bounds_f(gfx::SkRectToRectF(tab_mask.getBounds())); | 293 gfx::RectF tab_bounds_f(gfx::SkRectToRectF(tab_mask.getBounds())); |
296 views::View::ConvertRectToTarget(tab_, this, &tab_bounds_f); | 294 views::View::ConvertRectToTarget(tab_, this, &tab_bounds_f); |
(...skipping 12 matching lines...) Expand all Loading... |
309 int bottom_overflow = button_bounds.bottom() - tab_bounds.bottom(); | 307 int bottom_overflow = button_bounds.bottom() - tab_bounds.bottom(); |
310 if (top_overflow > 0) | 308 if (top_overflow > 0) |
311 button_bounds.set_y(tab_bounds.y()); | 309 button_bounds.set_y(tab_bounds.y()); |
312 else if (bottom_overflow > 0) | 310 else if (bottom_overflow > 0) |
313 button_bounds.set_height(button_bounds.height() - bottom_overflow); | 311 button_bounds.set_height(button_bounds.height() - bottom_overflow); |
314 | 312 |
315 return button_bounds; | 313 return button_bounds; |
316 } | 314 } |
317 | 315 |
318 // views::ViewTargeterDelegate: | 316 // views::ViewTargeterDelegate: |
319 virtual View* TargetForRect(View* root, const gfx::Rect& rect) override { | 317 View* TargetForRect(View* root, const gfx::Rect& rect) override { |
320 CHECK_EQ(root, this); | 318 CHECK_EQ(root, this); |
321 | 319 |
322 if (!views::UsePointBasedTargeting(rect)) | 320 if (!views::UsePointBasedTargeting(rect)) |
323 return ViewTargeterDelegate::TargetForRect(root, rect); | 321 return ViewTargeterDelegate::TargetForRect(root, rect); |
324 | 322 |
325 // Ignore the padding set on the button. | 323 // Ignore the padding set on the button. |
326 gfx::Rect contents_bounds = GetContentsBounds(); | 324 gfx::Rect contents_bounds = GetContentsBounds(); |
327 contents_bounds.set_x(GetMirroredXForRect(contents_bounds)); | 325 contents_bounds.set_x(GetMirroredXForRect(contents_bounds)); |
328 | 326 |
329 // Include the padding in hit-test for touch events. | 327 // Include the padding in hit-test for touch events. |
330 if (aura::Env::GetInstance()->is_touch_down()) | 328 if (aura::Env::GetInstance()->is_touch_down()) |
331 contents_bounds = GetLocalBounds(); | 329 contents_bounds = GetLocalBounds(); |
332 | 330 |
333 return contents_bounds.Intersects(rect) ? this : parent(); | 331 return contents_bounds.Intersects(rect) ? this : parent(); |
334 } | 332 } |
335 | 333 |
336 // views:MaskedTargeterDelegate: | 334 // views:MaskedTargeterDelegate: |
337 virtual bool GetHitTestMask(gfx::Path* mask) const override { | 335 bool GetHitTestMask(gfx::Path* mask) const override { |
338 DCHECK(mask); | 336 DCHECK(mask); |
339 mask->reset(); | 337 mask->reset(); |
340 | 338 |
341 // The parent tab may be partially occluded by another tab if we are | 339 // The parent tab may be partially occluded by another tab if we are |
342 // in stacked tab mode, which means that the tab close button may also | 340 // in stacked tab mode, which means that the tab close button may also |
343 // be partially occluded. Define the hit test mask of the tab close | 341 // be partially occluded. Define the hit test mask of the tab close |
344 // button to be the intersection of the parent tab's visible bounds | 342 // button to be the intersection of the parent tab's visible bounds |
345 // and the bounds of the tab close button. | 343 // and the bounds of the tab close button. |
346 gfx::Rect tab_bounds(GetTabBounds()); | 344 gfx::Rect tab_bounds(GetTabBounds()); |
347 gfx::Rect button_bounds(GetTabCloseButtonBounds(tab_bounds)); | 345 gfx::Rect button_bounds(GetTabCloseButtonBounds(tab_bounds)); |
348 gfx::Rect intersection(gfx::IntersectRects(tab_bounds, button_bounds)); | 346 gfx::Rect intersection(gfx::IntersectRects(tab_bounds, button_bounds)); |
349 | 347 |
350 if (!intersection.IsEmpty()) { | 348 if (!intersection.IsEmpty()) { |
351 mask->addRect(RectToSkRect(intersection)); | 349 mask->addRect(RectToSkRect(intersection)); |
352 return true; | 350 return true; |
353 } | 351 } |
354 | 352 |
355 return false; | 353 return false; |
356 } | 354 } |
357 | 355 |
358 virtual bool DoesIntersectRect(const View* target, | 356 bool DoesIntersectRect(const View* target, |
359 const gfx::Rect& rect) const override { | 357 const gfx::Rect& rect) const override { |
360 CHECK_EQ(target, this); | 358 CHECK_EQ(target, this); |
361 | 359 |
362 // If the request is not made in response to a gesture, use the | 360 // If the request is not made in response to a gesture, use the |
363 // default implementation. | 361 // default implementation. |
364 if (views::UsePointBasedTargeting(rect)) | 362 if (views::UsePointBasedTargeting(rect)) |
365 return MaskedTargeterDelegate::DoesIntersectRect(target, rect); | 363 return MaskedTargeterDelegate::DoesIntersectRect(target, rect); |
366 | 364 |
367 // The hit test request is in response to a gesture. Return false if any | 365 // The hit test request is in response to a gesture. Return false if any |
368 // part of the tab close button is hidden from the user. | 366 // part of the tab close button is hidden from the user. |
369 // TODO(tdanderson): Consider always returning the intersection if the | 367 // TODO(tdanderson): Consider always returning the intersection if the |
(...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1595 const gfx::ImageSkia& image) { | 1593 const gfx::ImageSkia& image) { |
1596 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); | 1594 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); |
1597 ImageCacheEntry entry; | 1595 ImageCacheEntry entry; |
1598 entry.resource_id = resource_id; | 1596 entry.resource_id = resource_id; |
1599 entry.scale_factor = scale_factor; | 1597 entry.scale_factor = scale_factor; |
1600 entry.image = image; | 1598 entry.image = image; |
1601 image_cache_->push_front(entry); | 1599 image_cache_->push_front(entry); |
1602 if (image_cache_->size() > kMaxImageCacheSize) | 1600 if (image_cache_->size() > kMaxImageCacheSize) |
1603 image_cache_->pop_back(); | 1601 image_cache_->pop_back(); |
1604 } | 1602 } |
OLD | NEW |