Chromium Code Reviews| Index: views/bubble/bubble_delegate.cc |
| diff --git a/views/bubble/bubble_delegate.cc b/views/bubble/bubble_delegate.cc |
| index 8d8228bdb4f1b28e15c0d0a5f970a0313145ca92..b4613774449a2b95bfbbe4265adafa02b9441d64 100644 |
| --- a/views/bubble/bubble_delegate.cc |
| +++ b/views/bubble/bubble_delegate.cc |
| @@ -33,22 +33,62 @@ BubbleDelegateView::BubbleDelegateView( |
| AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0)); |
| } |
| -BubbleDelegateView::~BubbleDelegateView() {} |
| +BubbleDelegateView::~BubbleDelegateView() { |
| + border_widget_->Close(); |
| +} |
| // static |
| Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate, |
| Widget* parent_widget) { |
| bubble_delegate->Init(); |
| - views::Widget* bubble_widget = new views::Widget(); |
| - views::Widget::InitParams params(views::Widget::InitParams::TYPE_BUBBLE); |
| - params.delegate = bubble_delegate; |
| - params.transparent = true; |
| + |
| + // Create a widget to host the border with transparency on. |
| + views::Widget* border_widget = new views::Widget(); |
| + views::Widget::InitParams border_params( |
| + views::Widget::InitParams::TYPE_BUBBLE); |
| + border_params.delegate = new BubbleBorderDelegateView(bubble_delegate); |
| + border_params.transparent = true; |
| if (!parent_widget) |
| - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| - params.parent_widget = parent_widget; |
| - bubble_widget->Init(params); |
| - bubble_widget->SetBounds(bubble_delegate->GetBubbleBounds()); |
| - return bubble_widget; |
| + border_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| + border_params.parent_widget = parent_widget; |
| + border_widget->Init(border_params); |
| + bubble_delegate->border_widget_ = border_widget; |
| + |
| + // Create a widget to host the content with transparency off. |
|
Ben Goodger (Google)
2011/10/25 15:29:36
pull the border widget init into a separate functi
msw
2011/10/27 02:01:45
Done (sort of, let me know what you think).
|
| + views::Widget* content_widget = new views::Widget(); |
| + views::Widget::InitParams content_params( |
| + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
| + content_params.delegate = bubble_delegate; |
| + content_params.transparent = false; |
| + content_params.parent_widget = border_widget; |
| + content_widget->Init(content_params); |
| + content_widget->SetContentsView(bubble_delegate); |
| + |
| + border_widget->SetBounds(bubble_delegate->GetBubbleBounds()); |
| + gfx::Rect content_bounds = border_widget->GetClientAreaScreenBounds(); |
| + content_bounds.Inset(bubble_delegate->GetBubbleFrameView()->GetInsets()); |
| + // TODO(msw): Adjust bounds so contents can't obscure the rounded corners. |
| + content_bounds.Inset(gfx::Insets(2, 2, 2, 2)); |
| + content_widget->SetBounds(content_bounds); |
| + |
| + // TODO(msw): Fixup show/close/hide/opacity, etc. |
| + content_widget->Show(); |
| + border_widget->Show(); |
| + |
| + // TODO(msw): Better transparency |
| + HWND hwnd = content_widget->GetNativeView(); |
| + SetWindowLong(hwnd, GWL_EXSTYLE, |
| + GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); |
| + |
| + // TODO(msw): Better content/border focus and z-ordering. |
| + //border_widget->MoveAboveWidget(content_widget); |
| + //content_widget->MoveAboveWidget(border_widget); |
| + //if (parent_widget) |
| + // parent_widget->MoveAboveWidget(border_widget); |
| + //border_widget->MoveToTop(); |
| + //content_widget->MoveToTop(); |
| + |
| + return content_widget; |
| } |
| View* BubbleDelegateView::GetInitiallyFocusedView() { |
| @@ -64,9 +104,7 @@ ClientView* BubbleDelegateView::CreateClientView(Widget* widget) { |
| } |
| NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView() { |
| - return new BubbleFrameView(GetArrowLocation(), |
| - GetPreferredSize(), |
| - GetColor()); |
| + return NULL; |
| } |
| gfx::Point BubbleDelegateView::GetAnchorPoint() const { |
| @@ -87,9 +125,21 @@ void BubbleDelegateView::StartFade(bool fade_in) { |
| fade_animation_.reset(new ui::SlideAnimation(this)); |
| fade_animation_->SetSlideDuration(kHideFadeDurationMS); |
| fade_animation_->Reset(fade_in ? 0.0 : 1.0); |
| + |
| + //// TODO(msw): Better transparency |
| + //HWND hwnd = GetWidget()->GetNativeView(); |
| + //SetWindowLong(hwnd, GWL_EXSTYLE, |
| + // GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); |
| + |
| if (fade_in) { |
| - GetWidget()->SetOpacity(0); |
| + border_widget_->SetOpacity(0); |
| + border_widget_->Show(); |
| + |
| + // TODO(msw): Better transparency like GetWidget()->SetOpacity(0); |
| + HWND hwnd = GetWidget()->GetNativeView(); |
| + SetLayeredWindowAttributes(hwnd, 0, 0, LWA_ALPHA); |
| GetWidget()->Show(); |
| + |
| fade_animation_->Show(); |
| } else { |
| fade_animation_->Hide(); |
| @@ -109,6 +159,12 @@ void BubbleDelegateView::AnimationEnded(const ui::Animation* animation) { |
| DCHECK_EQ(animation, fade_animation_.get()); |
| bool closed = fade_animation_->GetCurrentValue() == 0; |
| fade_animation_->Reset(); |
| + |
| + //// TODO(msw): Better transparency |
| + //HWND hwnd = GetWidget()->GetNativeView(); |
| + //SetWindowLong(hwnd, GWL_EXSTYLE, |
| + // GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); |
| + |
| if (closed) |
| GetWidget()->Close(); |
| } |
| @@ -116,7 +172,14 @@ void BubbleDelegateView::AnimationEnded(const ui::Animation* animation) { |
| void BubbleDelegateView::AnimationProgressed(const ui::Animation* animation) { |
| DCHECK_EQ(animation, fade_animation_.get()); |
| DCHECK(fade_animation_->is_animating()); |
| - GetWidget()->SetOpacity(fade_animation_->GetCurrentValue() * 255); |
| + unsigned char opacity = fade_animation_->GetCurrentValue() * 255; |
| + |
| + // TODO(msw): Better transparency like GetWidget()->SetOpacity(opacity); |
| + HWND hwnd = GetWidget()->GetNativeView(); |
| + SetLayeredWindowAttributes(hwnd, 0, opacity, LWA_ALPHA); |
| + |
| + border_widget_->SetOpacity(opacity); |
| + border_widget_->non_client_view()->SchedulePaint(); |
| SchedulePaint(); |
| } |
| @@ -126,7 +189,7 @@ const BubbleView* BubbleDelegateView::GetBubbleView() const { |
| const BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const { |
| return static_cast<BubbleFrameView*>( |
| - GetWidget()->non_client_view()->frame_view()); |
| + border_widget_->non_client_view()->frame_view()); |
| } |
| gfx::Rect BubbleDelegateView::GetBubbleBounds() { |
| @@ -136,4 +199,23 @@ gfx::Rect BubbleDelegateView::GetBubbleBounds() { |
| gfx::Rect(GetAnchorPoint(), GetPreferredSize())); |
| } |
| +BubbleBorderDelegateView::BubbleBorderDelegateView(BubbleDelegateView* bubble) |
| + : bubble_(bubble) {} |
| + |
| +BubbleBorderDelegateView::~BubbleBorderDelegateView() {} |
| + |
| +View* BubbleBorderDelegateView::GetContentsView() { |
| + return this; |
| +} |
| + |
| +ClientView* BubbleBorderDelegateView::CreateClientView(Widget* widget) { |
| + return new ClientView(widget, GetContentsView()); |
| +} |
| + |
| +NonClientFrameView* BubbleBorderDelegateView::CreateNonClientFrameView() { |
| + return new BubbleFrameView(bubble_->GetArrowLocation(), |
| + bubble_->GetPreferredSize(), |
| + bubble_->GetColor()); |
| +} |
| + |
| } // namespace views |