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 |