Index: views/bubble/bubble_delegate.cc |
diff --git a/views/bubble/bubble_delegate.cc b/views/bubble/bubble_delegate.cc |
index b46e3536bf73feba52fed2035c22b8abb319c331..aac3e1fcdb65ab3627252af1e3be13a897577629 100644 |
--- a/views/bubble/bubble_delegate.cc |
+++ b/views/bubble/bubble_delegate.cc |
@@ -9,15 +9,72 @@ |
#include "views/widget/widget.h" |
// The duration of the fade animation in milliseconds. |
-static const int kHideFadeDurationMS = 1000; |
+static const int kHideFadeDurationMS = 200; |
namespace views { |
+namespace { |
+ |
+// Create a widget to host the bubble. |
+Widget* CreateBubbleWidget(BubbleDelegateView* bubble, Widget* parent) { |
+ Widget* bubble_widget = new Widget(); |
+ Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE); |
+ bubble_params.delegate = bubble; |
+ bubble_params.transparent = true; |
+ bubble_params.parent_widget = parent; |
+ if (!bubble_params.parent_widget) |
+ bubble_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
+#if defined(OS_WIN) && !defined(USE_AURA) |
+ bubble_params.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS; |
+ bubble_params.transparent = false; |
+#endif |
+ bubble_widget->Init(bubble_params); |
+ return bubble_widget; |
+} |
+ |
+#if defined(OS_WIN) && !defined(USE_AURA) |
+// The border widget's delegate, needed for transparent Windows native controls. |
+// TODO(msw): Remove this when Windows native controls are no longer needed. |
+class VIEWS_EXPORT BubbleBorderDelegateView : public WidgetDelegateView { |
+ public: |
+ explicit BubbleBorderDelegateView(BubbleDelegateView* bubble) |
+ : bubble_(bubble) {} |
Ben Goodger (Google)
2011/10/27 15:37:00
nit: 4-space indent instead of 2.
msw
2011/10/28 17:10:18
Done.
|
+ virtual ~BubbleBorderDelegateView() {} |
+ |
+ // WidgetDelegateView overrides: |
+ virtual bool CanActivate() const OVERRIDE { return false; } |
+ virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE { |
+ return bubble_->CreateNonClientFrameView(); |
+ } |
+ |
+ private: |
+ BubbleDelegateView* bubble_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BubbleBorderDelegateView); |
+}; |
+ |
+// Create a widget to host the bubble's border. |
+Widget* CreateBorderWidget(BubbleDelegateView* bubble, Widget* parent) { |
+ Widget* border_widget = new Widget(); |
+ Widget::InitParams border_params(Widget::InitParams::TYPE_BUBBLE); |
+ border_params.delegate = new BubbleBorderDelegateView(bubble); |
+ border_params.transparent = true; |
+ border_params.parent_widget = parent; |
+ if (!border_params.parent_widget) |
+ border_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
+ border_widget->Init(border_params); |
+ return border_widget; |
+} |
+#endif |
+ |
+} // namespace |
+ |
BubbleDelegateView::BubbleDelegateView() |
- : WidgetDelegateView(), |
- close_on_esc_(true), |
+ : close_on_esc_(true), |
arrow_location_(BubbleBorder::TOP_LEFT), |
- color_(SK_ColorWHITE) { |
+ color_(SK_ColorWHITE), |
+ border_widget_(NULL) { |
+ set_background(views::Background::CreateSolidBackground(color_)); |
AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0)); |
} |
@@ -25,29 +82,39 @@ BubbleDelegateView::BubbleDelegateView( |
const gfx::Point& anchor_point, |
BubbleBorder::ArrowLocation arrow_location, |
const SkColor& color) |
- : WidgetDelegateView(), |
- close_on_esc_(true), |
+ : close_on_esc_(true), |
anchor_point_(anchor_point), |
arrow_location_(arrow_location), |
- color_(color) { |
+ color_(color), |
+ border_widget_(NULL) { |
+ set_background(views::Background::CreateSolidBackground(color_)); |
AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0)); |
} |
-BubbleDelegateView::~BubbleDelegateView() {} |
+BubbleDelegateView::~BubbleDelegateView() { |
+ if (border_widget_) |
+ 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; |
- if (!parent_widget) |
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
- params.parent_widget = parent_widget; |
- bubble_widget->Init(params); |
+ Widget* bubble_widget = CreateBubbleWidget(bubble_delegate, parent_widget); |
+ |
+#if defined(OS_WIN) && !defined(USE_AURA) |
+ Widget* border_widget = CreateBorderWidget(bubble_delegate, parent_widget); |
Ben Goodger (Google)
2011/10/27 15:37:00
Move the border initialization into a separate fun
msw
2011/10/28 17:10:18
Only 3 lines were initializing the border, but I s
|
+ bubble_delegate->border_widget_ = border_widget; |
+ bubble_widget->SetContentsView(bubble_delegate->GetContentsView()); |
+ border_widget->SetBounds(bubble_delegate->GetBubbleBounds()); |
+ gfx::Rect client_bounds( |
+ bubble_delegate->GetBubbleFrameView()->GetBoundsForClientView()); |
+ client_bounds.Offset(border_widget->GetWindowScreenBounds().origin()); |
+ bubble_widget->SetBounds(client_bounds); |
+#else |
bubble_widget->SetBounds(bubble_delegate->GetBubbleBounds()); |
+#endif |
+ |
return bubble_widget; |
} |
@@ -59,10 +126,6 @@ View* BubbleDelegateView::GetContentsView() { |
return this; |
} |
-ClientView* BubbleDelegateView::CreateClientView(Widget* widget) { |
- return new ClientView(widget, GetContentsView()); |
-} |
- |
NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView() { |
return new BubbleFrameView(GetArrowLocation(), |
GetPreferredSize(), |
@@ -81,15 +144,29 @@ SkColor BubbleDelegateView::GetColor() const { |
return color_; |
} |
-void BubbleDelegateView::Init() {} |
+void BubbleDelegateView::Show() { |
+ if (border_widget_) |
+ border_widget_->Show(); |
+ GetWidget()->Show(); |
+ GetFocusManager()->SetFocusedView(GetInitiallyFocusedView()); |
+} |
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); |
+ |
+#if defined(OS_WIN) && !defined(USE_AURA) |
+ HWND hwnd = GetWidget()->GetNativeView(); |
+ SetWindowLong(hwnd, GWL_EXSTYLE, |
+ GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); |
Ben Goodger (Google)
2011/10/27 15:37:00
Question: Can we do this in NativeWidgetWin::SetOp
msw
2011/10/28 17:10:18
Moved into AnimationProgressed. We don't want to t
|
+#endif |
+ |
if (fade_in) { |
+ if (border_widget_) |
+ border_widget_->SetOpacity(0); |
GetWidget()->SetOpacity(0); |
- GetWidget()->Show(); |
+ Show(); |
fade_animation_->Show(); |
} else { |
fade_animation_->Hide(); |
@@ -105,10 +182,19 @@ bool BubbleDelegateView::AcceleratorPressed(const Accelerator& accelerator) { |
return true; |
} |
+void BubbleDelegateView::Init() {} |
+ |
void BubbleDelegateView::AnimationEnded(const ui::Animation* animation) { |
DCHECK_EQ(animation, fade_animation_.get()); |
bool closed = fade_animation_->GetCurrentValue() == 0; |
fade_animation_->Reset(); |
+ |
+#if defined(OS_WIN) && !defined(USE_AURA) |
+ HWND hwnd = GetWidget()->GetNativeView(); |
+ SetWindowLong(hwnd, GWL_EXSTYLE, |
+ GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); |
Ben Goodger (Google)
2011/10/27 15:37:00
Again, in NativeWidgetWin::SetOpacity() when setti
msw
2011/10/28 17:10:18
Ditto to the StartFade comment.
|
+#endif |
+ |
if (closed) |
GetWidget()->Close(); |
} |
@@ -116,7 +202,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; |
+#if defined(OS_WIN) && !defined(USE_AURA) |
+ HWND hwnd = GetWidget()->GetNativeView(); |
+ SetLayeredWindowAttributes(hwnd, 0, opacity, LWA_ALPHA); |
Ben Goodger (Google)
2011/10/27 15:37:00
Here, can we call SetOpacity() on GetWidget()?
msw
2011/10/28 17:10:18
Nope, as you pointed out, we need to use SetLayere
|
+ border_widget_->SetOpacity(opacity); |
+ border_widget_->non_client_view()->SchedulePaint(); |
+#endif |
+ GetWidget()->SetOpacity(opacity); |
SchedulePaint(); |
} |
@@ -126,7 +219,11 @@ const BubbleView* BubbleDelegateView::GetBubbleView() const { |
const BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const { |
return static_cast<BubbleFrameView*>( |
+#if defined(OS_WIN) && !defined(USE_AURA) |
+ border_widget_->non_client_view()->frame_view()); |
+#else |
GetWidget()->non_client_view()->frame_view()); |
+#endif |
} |
gfx::Rect BubbleDelegateView::GetBubbleBounds() { |