Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Unified Diff: views/bubble/bubble_delegate.cc

Issue 8368006: Support Windows native textfield, combobox, etc. in new bubbles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync and merge. Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: views/bubble/bubble_delegate.cc
diff --git a/views/bubble/bubble_delegate.cc b/views/bubble/bubble_delegate.cc
index 1fb7ebf56cf7e86b4e51e14fc1691d2ecc311a82..1b40c29ae1b47cf9230c48dc44f830a2272bf2c7 100644
--- a/views/bubble/bubble_delegate.cc
+++ b/views/bubble/bubble_delegate.cc
@@ -9,15 +9,76 @@
#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) {}
+ virtual ~BubbleBorderDelegateView() {}
+
+ // WidgetDelegateView overrides:
+ virtual bool CanActivate() const OVERRIDE;
+ virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE;
+
+ private:
+ BubbleDelegateView* bubble_;
+
+ DISALLOW_COPY_AND_ASSIGN(BubbleBorderDelegateView);
+};
+
+bool BubbleBorderDelegateView::CanActivate() const { return false; }
+
+NonClientFrameView* BubbleBorderDelegateView::CreateNonClientFrameView() {
+ return bubble_->CreateNonClientFrameView();
+}
+
+// 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,30 +86,35 @@ 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),
- original_opacity_(255) {
+ original_opacity_(255),
+ 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)
+ bubble_delegate->InitializeBorderWidget(parent_widget);
+ bubble_widget->SetContentsView(bubble_delegate->GetContentsView());
+ bubble_widget->SetBounds(bubble_delegate->GetBubbleClientBounds());
+#else
bubble_widget->SetBounds(bubble_delegate->GetBubbleBounds());
+#endif
+
return bubble_widget;
}
@@ -60,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(),
@@ -82,7 +144,12 @@ 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));
@@ -90,8 +157,10 @@ void BubbleDelegateView::StartFade(bool fade_in) {
fade_animation_->Reset(fade_in ? 0.0 : 1.0);
if (fade_in) {
original_opacity_ = 0;
+ if (border_widget_)
+ border_widget_->SetOpacity(original_opacity_);
GetWidget()->SetOpacity(original_opacity_);
- GetWidget()->Show();
+ Show();
fade_animation_->Show();
} else {
original_opacity_ = 255;
@@ -101,6 +170,8 @@ void BubbleDelegateView::StartFade(bool fade_in) {
void BubbleDelegateView::ResetFade() {
fade_animation_.reset();
+ if (border_widget_)
+ border_widget_->SetOpacity(original_opacity_);
GetWidget()->SetOpacity(original_opacity_);
}
@@ -113,6 +184,8 @@ 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;
@@ -124,17 +197,28 @@ 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)
+ // Explicitly set the content Widget's layered style and set transparency via
+ // SetLayeredWindowAttributes. This is done because initializing the Widget as
+ // transparent and setting opacity via UpdateLayeredWindow doesn't support
+ // hosting child native Windows controls.
+ const HWND hwnd = GetWidget()->GetNativeView();
+ const DWORD style = GetWindowLong(hwnd, GWL_EXSTYLE);
+ if ((opacity == 255) == !!(style & WS_EX_LAYERED))
+ SetWindowLong(hwnd, GWL_EXSTYLE, style ^ WS_EX_LAYERED);
+ SetLayeredWindowAttributes(hwnd, 0, opacity, LWA_ALPHA);
+ // Update the border widget's opacity.
+ border_widget_->SetOpacity(opacity);
+ border_widget_->non_client_view()->SchedulePaint();
+#endif
+ GetWidget()->SetOpacity(opacity);
SchedulePaint();
}
-const BubbleView* BubbleDelegateView::GetBubbleView() const {
- return GetWidget()->client_view()->AsBubbleView();
-}
-
-const BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
- return static_cast<BubbleFrameView*>(
- GetWidget()->non_client_view()->frame_view());
+BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
+ const Widget* widget = border_widget_ ? border_widget_ : GetWidget();
+ return static_cast<BubbleFrameView*>(widget->non_client_view()->frame_view());
}
gfx::Rect BubbleDelegateView::GetBubbleBounds() {
@@ -144,4 +228,17 @@ gfx::Rect BubbleDelegateView::GetBubbleBounds() {
gfx::Rect(GetAnchorPoint(), GetPreferredSize()));
}
+#if defined(OS_WIN) && !defined(USE_AURA)
+void BubbleDelegateView::InitializeBorderWidget(Widget* parent_widget) {
+ border_widget_ = CreateBorderWidget(this, parent_widget);
+ border_widget_->SetBounds(GetBubbleBounds());
+}
+
+gfx::Rect BubbleDelegateView::GetBubbleClientBounds() const {
+ gfx::Rect client_bounds(GetBubbleFrameView()->GetBoundsForClientView());
+ client_bounds.Offset(border_widget_->GetWindowScreenBounds().origin());
+ return client_bounds;
+}
+#endif
+
} // namespace views

Powered by Google App Engine
This is Rietveld 408576698