15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h" 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/slide_animation.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/color_utils.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/native_theme/native_theme.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_frame_view.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/views/focus/view_storage.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget_observer.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN) 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/win/shell.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The duration of the fade animation in milliseconds. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kHideFadeDurationMS = 200; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The defaut margin between the content and the inside border, in pixels. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDefaultMargin = 6; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Create a widget to host the bubble. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Widget* CreateBubbleWidget(BubbleDelegateView* bubble) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Widget* bubble_widget = new Widget(); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_params.delegate = bubble; 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bubble_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_params.accept_events = bubble->accept_events(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bubble->parent_window()) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_params.parent = bubble->parent_window(); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (bubble->anchor_widget()) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bubble_params.parent = bubble->anchor_widget()->GetNativeView(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_params.can_activate = bubble->CanActivate(); 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble->OnBeforeBubbleWidgetInit(&bubble_params, bubble_widget); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_widget->Init(bubble_params); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bubble_widget; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace 4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BubbleDelegateView::BubbleDelegateView() 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : close_on_esc_(true), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_on_deactivate_(true), 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_widget_(NULL), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) move_with_anchor_(false), 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) arrow_(BubbleBorder::TOP_LEFT), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shadow_(BubbleBorder::SMALL_SHADOW), 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) color_explicitly_set_(false), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins_(kDefaultMargin, kDefaultMargin, kDefaultMargin, kDefaultMargin), 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_opacity_(255), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_focusless_(false), 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_events_(true), 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) border_accepts_events_(true), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) adjust_if_offscreen_(true), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_window_(NULL) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateColorsFromTheme(GetNativeTheme()); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BubbleDelegateView::BubbleDelegateView( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* anchor_view, 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BubbleBorder::Arrow arrow) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : close_on_esc_(true), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_on_deactivate_(true), 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_widget_(NULL), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) move_with_anchor_(false), 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) arrow_(arrow), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shadow_(BubbleBorder::SMALL_SHADOW), 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) color_explicitly_set_(false), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins_(kDefaultMargin, kDefaultMargin, kDefaultMargin, kDefaultMargin), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_opacity_(255), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_focusless_(false), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_events_(true), 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) border_accepts_events_(true), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) adjust_if_offscreen_(true), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_window_(NULL) { 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetAnchorView(anchor_view); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateColorsFromTheme(GetNativeTheme()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BubbleDelegateView::~BubbleDelegateView() { 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SetLayoutManager(NULL); 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetAnchorView(NULL); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_delegate->Init(); 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Get the latest anchor widget from the anchor view at bubble creation time. 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bubble_delegate->SetAnchorView(bubble_delegate->GetAnchorView()); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Widget* bubble_widget = CreateBubbleWidget(bubble_delegate); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN) && defined(USE_AURA) 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If glass is enabled, the bubble is allowed to extend outside the bounds of 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // the parent frame and let DWM handle compositing. If not, then we don't 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // want to allow the bubble to extend the frame because it will be clipped. 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bubble_delegate->set_adjust_if_offscreen(ui::win::IsAeroGlassEnabled()); 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_delegate->SizeToContents(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_widget->AddObserver(bubble_delegate); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bubble_widget; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BubbleDelegateView* BubbleDelegateView::AsBubbleDelegate() { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BubbleDelegateView::CanActivate() const { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !use_focusless(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool BubbleDelegateView::ShouldShowCloseButton() const { 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)View* BubbleDelegateView::GetContentsView() { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView( 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Widget* widget) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BubbleFrameView* frame = new BubbleFrameView(margins()); 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BubbleBorder::Arrow adjusted_arrow = arrow(); 137d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (base::i18n::IsRTL()) 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) adjusted_arrow = BubbleBorder::horizontal_mirror(adjusted_arrow); 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame->SetBubbleBorder(new BubbleBorder(adjusted_arrow, shadow(), color())); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return frame; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BubbleDelegateView::GetAccessibleState(ui::AccessibleViewState* state) { 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state->role = ui::AccessibilityTypes::ROLE_DIALOG; 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BubbleDelegateView::OnWidgetDestroying(Widget* widget) { 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (anchor_widget() == widget) 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetAnchorView(NULL); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void BubbleDelegateView::OnWidgetVisibilityChanging(Widget* widget, 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool visible) { 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN) 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // On Windows we need to handle this before the bubble is visible or hidden. 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Please see the comment on the OnWidgetVisibilityChanging function. On 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // other platforms it is fine to handle it after the bubble is shown/hidden. 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) HandleVisibilityChanged(widget, visible); 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BubbleDelegateView::OnWidgetVisibilityChanged(Widget* widget, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool visible) { 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_WIN) 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) HandleVisibilityChanged(widget, visible); 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool active) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (close_on_deactivate() && widget == GetWidget() && !active) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->Close(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BubbleDelegateView::OnWidgetBoundsChanged(Widget* widget, 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& new_bounds) { 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (anchor_widget() == widget) { 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (move_with_anchor()) 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SizeToContents(); 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) else 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GetWidget()->Close(); 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)View* BubbleDelegateView::GetAnchorView() const { 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return ViewStorage::GetInstance()->RetrieveView(anchor_view_storage_id_); 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect BubbleDelegateView::GetAnchorRect() { 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!GetAnchorView()) 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return anchor_rect_; 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) anchor_rect_ = GetAnchorView()->GetBoundsInScreen(); 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) anchor_rect_.Inset(anchor_view_insets_); 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return anchor_rect_; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BubbleDelegateView::OnBeforeBubbleWidgetInit(Widget::InitParams* params, 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Widget* widget) const { 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BubbleDelegateView::StartFade(bool fade_in) { 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_AURA) 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Use AURA's window layer animation instead of fading. This ensures that 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // hosts which rely on the layer animation callbacks to close the window 2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // work correctly. 2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (fade_in) 2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GetWidget()->Show(); 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) else 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GetWidget()->Close(); 2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#else 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) fade_animation_.reset(new gfx::SlideAnimation(this)); 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) fade_animation_->SetSlideDuration(GetFadeDuration()); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fade_animation_->Reset(fade_in ? 0.0 : 1.0); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fade_in) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_opacity_ = 0; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->SetOpacity(original_opacity_); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetWidget()->Show(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fade_animation_->Show(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_opacity_ = 255; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fade_animation_->Hide(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BubbleDelegateView::ResetFade() { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fade_animation_.reset(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->SetOpacity(original_opacity_); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BubbleDelegateView::SetAlignment(BubbleBorder::BubbleAlignment alignment) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBubbleFrameView()->bubble_border()->set_alignment(alignment); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SizeToContents(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BubbleDelegateView::SetArrowPaintType( 2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BubbleBorder::ArrowPaintType paint_type) { 2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GetBubbleFrameView()->bubble_border()->set_paint_arrow(paint_type); 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SizeToContents(); 2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BubbleDelegateView::OnAnchorBoundsChanged() { 2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SizeToContents(); 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BubbleDelegateView::AcceleratorPressed( 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::Accelerator& accelerator) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fade_animation_.get()) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fade_animation_->Reset(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->Close(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BubbleDelegateView::OnNativeThemeChanged(const ui::NativeTheme* theme) { 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateColorsFromTheme(theme); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void BubbleDelegateView::AnimationEnded(const gfx::Animation* animation) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (animation != fade_animation_.get()) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool closed = fade_animation_->GetCurrentValue() == 0; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fade_animation_->Reset(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (closed) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->Close(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void BubbleDelegateView::AnimationProgressed(const gfx::Animation* animation) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (animation != fade_animation_.get()) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fade_animation_->is_animating()); 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetWidget()->SetOpacity(fade_animation_->GetCurrentValue() * 255); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BubbleDelegateView::Init() {} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BubbleDelegateView::SetAnchorView(View* anchor_view) { 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // When the anchor view gets set the associated anchor widget might 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // change as well. 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!anchor_view || anchor_widget() != anchor_view->GetWidget()) { 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (anchor_widget()) { 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) anchor_widget_->RemoveObserver(this); 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) anchor_widget_ = NULL; 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (anchor_view) { 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) anchor_widget_ = anchor_view->GetWidget(); 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (anchor_widget_) 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) anchor_widget_->AddObserver(this); 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Remove the old storage item and set the new (if there is one). 2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ViewStorage* view_storage = ViewStorage::GetInstance(); 2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (view_storage->RetrieveView(anchor_view_storage_id_)) 2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) view_storage->RemoveView(anchor_view_storage_id_); 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (anchor_view) 2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) view_storage->StoreView(anchor_view_storage_id_, anchor_view); 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (GetWidget()) 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnAnchorBoundsChanged(); 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BubbleDelegateView::SetAnchorRect(const gfx::Rect& rect) { 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) anchor_rect_ = rect; 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (GetWidget()) 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnAnchorBoundsChanged(); 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BubbleDelegateView::SizeToContents() { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->SetBounds(GetBubbleBounds()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const { 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const NonClientView* view = 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetWidget() ? GetWidget()->non_client_view() : NULL; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view ? static_cast<BubbleFrameView*>(view->frame_view()) : NULL; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect BubbleDelegateView::GetBubbleBounds() { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The argument rect has its origin at the bubble's arrow anchor point; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its size is the preferred size of the bubble's client view (this view). 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetBubbleFrameView()->GetUpdatedWindowBounds(GetAnchorRect(), 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetPreferredSize(), adjust_if_offscreen_); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int BubbleDelegateView::GetFadeDuration() { 3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return kHideFadeDurationMS; 3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BubbleDelegateView::UpdateColorsFromTheme(const ui::NativeTheme* theme) { 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!color_explicitly_set_) { 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) color_ = GetNativeTheme()->GetSystemColor( 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::NativeTheme::kColorId_WindowBackground); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_background(Background::CreateSolidBackground(color())); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BubbleFrameView* frame_view = GetBubbleFrameView(); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frame_view) 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame_view->bubble_border()->set_background_color(color()); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BubbleDelegateView::HandleVisibilityChanged(Widget* widget, bool visible) { 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (widget == GetWidget() && visible && anchor_widget() && 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) anchor_widget()->GetTopLevelWidget()) { 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) anchor_widget()->GetTopLevelWidget()->DisableInactiveRendering(); 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace views 351