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

Side by Side 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: Eliminate Widget return. Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "views/bubble/bubble_delegate.h" 5 #include "views/bubble/bubble_delegate.h"
6 6
7 #include "ui/base/animation/slide_animation.h" 7 #include "ui/base/animation/slide_animation.h"
8 #include "views/bubble/bubble_frame_view.h" 8 #include "views/bubble/bubble_frame_view.h"
9 #include "views/widget/widget.h" 9 #include "views/widget/widget.h"
10 10
11 // The duration of the fade animation in milliseconds. 11 // The duration of the fade animation in milliseconds.
12 static const int kHideFadeDurationMS = 1000; 12 static const int kHideFadeDurationMS = 200;
13 13
14 namespace views { 14 namespace views {
15 15
16 namespace {
17
18 // Create a widget to host the bubble.
19 Widget* CreateBubbleWidget(BubbleDelegateView* bubble, Widget* parent) {
20 Widget* bubble_widget = new Widget();
21 Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE);
22 bubble_params.delegate = bubble;
23 bubble_params.transparent = true;
24 bubble_params.parent_widget = parent;
25 if (!bubble_params.parent_widget)
26 bubble_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
27 #if defined(OS_WIN) && !defined(USE_AURA)
28 bubble_params.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS;
29 bubble_params.transparent = false;
30 #endif
31 bubble_widget->Init(bubble_params);
32 return bubble_widget;
33 }
34
35 #if defined(OS_WIN) && !defined(USE_AURA)
36 // The border widget's delegate, needed for transparent Windows native controls.
37 // TODO(msw): Remove this when Windows native controls are no longer needed.
38 class VIEWS_EXPORT BubbleBorderDelegateView : public WidgetDelegateView {
39 public:
40 explicit BubbleBorderDelegateView(BubbleDelegateView* bubble)
41 : bubble_(bubble) {}
42 virtual ~BubbleBorderDelegateView() {}
43
44 // WidgetDelegateView overrides:
45 virtual bool CanActivate() const OVERRIDE;
46 virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE;
47
48 private:
49 BubbleDelegateView* bubble_;
50
51 DISALLOW_COPY_AND_ASSIGN(BubbleBorderDelegateView);
52 };
53
54 bool BubbleBorderDelegateView::CanActivate() const { return false; }
55
56 NonClientFrameView* BubbleBorderDelegateView::CreateNonClientFrameView() {
57 return bubble_->CreateNonClientFrameView();
58 }
59
60 // Create a widget to host the bubble's border.
61 Widget* CreateBorderWidget(BubbleDelegateView* bubble, Widget* parent) {
62 Widget* border_widget = new Widget();
63 Widget::InitParams border_params(Widget::InitParams::TYPE_BUBBLE);
64 border_params.delegate = new BubbleBorderDelegateView(bubble);
65 border_params.transparent = true;
66 border_params.parent_widget = parent;
67 if (!border_params.parent_widget)
68 border_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
69 border_widget->Init(border_params);
70 return border_widget;
71 }
72 #endif
73
74 } // namespace
75
16 BubbleDelegateView::BubbleDelegateView() 76 BubbleDelegateView::BubbleDelegateView()
17 : WidgetDelegateView(), 77 : close_on_esc_(true),
18 close_on_esc_(true),
19 arrow_location_(BubbleBorder::TOP_LEFT), 78 arrow_location_(BubbleBorder::TOP_LEFT),
20 color_(SK_ColorWHITE) { 79 color_(SK_ColorWHITE),
80 border_widget_(NULL) {
81 set_background(views::Background::CreateSolidBackground(color_));
21 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0)); 82 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0));
22 } 83 }
23 84
24 BubbleDelegateView::BubbleDelegateView( 85 BubbleDelegateView::BubbleDelegateView(
25 const gfx::Point& anchor_point, 86 const gfx::Point& anchor_point,
26 BubbleBorder::ArrowLocation arrow_location, 87 BubbleBorder::ArrowLocation arrow_location,
27 const SkColor& color) 88 const SkColor& color)
28 : WidgetDelegateView(), 89 : close_on_esc_(true),
29 close_on_esc_(true),
30 anchor_point_(anchor_point), 90 anchor_point_(anchor_point),
31 arrow_location_(arrow_location), 91 arrow_location_(arrow_location),
32 color_(color), 92 color_(color),
33 original_opacity_(255) { 93 original_opacity_(255),
94 border_widget_(NULL) {
95 set_background(views::Background::CreateSolidBackground(color_));
34 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0)); 96 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0));
35 } 97 }
36 98
37 BubbleDelegateView::~BubbleDelegateView() {} 99 BubbleDelegateView::~BubbleDelegateView() {
100 if (border_widget_)
101 border_widget_->Close();
102 }
38 103
39 // static 104 // static
40 Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate, 105 void BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate,
41 Widget* parent_widget) { 106 Widget* parent_widget) {
42 bubble_delegate->Init(); 107 bubble_delegate->Init();
43 views::Widget* bubble_widget = new views::Widget(); 108 Widget* bubble_widget = CreateBubbleWidget(bubble_delegate, parent_widget);
44 views::Widget::InitParams params(views::Widget::InitParams::TYPE_BUBBLE); 109
45 params.delegate = bubble_delegate; 110 #if defined(OS_WIN) && !defined(USE_AURA)
46 params.transparent = true; 111 bubble_delegate->InitializeBorderWidget(parent_widget);
47 if (!parent_widget) 112 bubble_widget->SetContentsView(bubble_delegate->GetContentsView());
48 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 113 bubble_widget->SetBounds(bubble_delegate->GetBubbleClientBounds());
49 params.parent_widget = parent_widget; 114 #else
50 bubble_widget->Init(params);
51 bubble_widget->SetBounds(bubble_delegate->GetBubbleBounds()); 115 bubble_widget->SetBounds(bubble_delegate->GetBubbleBounds());
52 return bubble_widget; 116 #endif
53 } 117 }
54 118
55 View* BubbleDelegateView::GetInitiallyFocusedView() { 119 View* BubbleDelegateView::GetInitiallyFocusedView() {
56 return this; 120 return this;
57 } 121 }
58 122
59 View* BubbleDelegateView::GetContentsView() { 123 View* BubbleDelegateView::GetContentsView() {
60 return this; 124 return this;
61 } 125 }
62 126
63 ClientView* BubbleDelegateView::CreateClientView(Widget* widget) {
64 return new ClientView(widget, GetContentsView());
65 }
66
67 NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView() { 127 NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView() {
68 return new BubbleFrameView(GetArrowLocation(), 128 return new BubbleFrameView(GetArrowLocation(),
69 GetPreferredSize(), 129 GetPreferredSize(),
70 GetColor()); 130 GetColor());
71 } 131 }
72 132
73 gfx::Point BubbleDelegateView::GetAnchorPoint() { 133 gfx::Point BubbleDelegateView::GetAnchorPoint() {
74 return anchor_point_; 134 return anchor_point_;
75 } 135 }
76 136
77 BubbleBorder::ArrowLocation BubbleDelegateView::GetArrowLocation() const { 137 BubbleBorder::ArrowLocation BubbleDelegateView::GetArrowLocation() const {
78 return arrow_location_; 138 return arrow_location_;
79 } 139 }
80 140
81 SkColor BubbleDelegateView::GetColor() const { 141 SkColor BubbleDelegateView::GetColor() const {
82 return color_; 142 return color_;
83 } 143 }
84 144
85 void BubbleDelegateView::Init() {} 145 void BubbleDelegateView::Show() {
146 if (border_widget_)
147 border_widget_->Show();
148 GetWidget()->Show();
149 GetFocusManager()->SetFocusedView(GetInitiallyFocusedView());
150 }
86 151
87 void BubbleDelegateView::StartFade(bool fade_in) { 152 void BubbleDelegateView::StartFade(bool fade_in) {
88 fade_animation_.reset(new ui::SlideAnimation(this)); 153 fade_animation_.reset(new ui::SlideAnimation(this));
89 fade_animation_->SetSlideDuration(kHideFadeDurationMS); 154 fade_animation_->SetSlideDuration(kHideFadeDurationMS);
90 fade_animation_->Reset(fade_in ? 0.0 : 1.0); 155 fade_animation_->Reset(fade_in ? 0.0 : 1.0);
91 if (fade_in) { 156 if (fade_in) {
92 original_opacity_ = 0; 157 original_opacity_ = 0;
158 if (border_widget_)
159 border_widget_->SetOpacity(original_opacity_);
93 GetWidget()->SetOpacity(original_opacity_); 160 GetWidget()->SetOpacity(original_opacity_);
94 GetWidget()->Show(); 161 Show();
95 fade_animation_->Show(); 162 fade_animation_->Show();
96 } else { 163 } else {
97 original_opacity_ = 255; 164 original_opacity_ = 255;
98 fade_animation_->Hide(); 165 fade_animation_->Hide();
99 } 166 }
100 } 167 }
101 168
102 void BubbleDelegateView::ResetFade() { 169 void BubbleDelegateView::ResetFade() {
103 fade_animation_.reset(); 170 fade_animation_.reset();
171 if (border_widget_)
172 border_widget_->SetOpacity(original_opacity_);
104 GetWidget()->SetOpacity(original_opacity_); 173 GetWidget()->SetOpacity(original_opacity_);
105 } 174 }
106 175
107 bool BubbleDelegateView::AcceleratorPressed(const Accelerator& accelerator) { 176 bool BubbleDelegateView::AcceleratorPressed(const Accelerator& accelerator) {
108 if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE) 177 if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
109 return false; 178 return false;
110 if (fade_animation_.get()) 179 if (fade_animation_.get())
111 fade_animation_->Reset(); 180 fade_animation_->Reset();
112 GetWidget()->Close(); 181 GetWidget()->Close();
113 return true; 182 return true;
114 } 183 }
115 184
185 void BubbleDelegateView::Init() {}
186
116 void BubbleDelegateView::AnimationEnded(const ui::Animation* animation) { 187 void BubbleDelegateView::AnimationEnded(const ui::Animation* animation) {
117 DCHECK_EQ(animation, fade_animation_.get()); 188 DCHECK_EQ(animation, fade_animation_.get());
118 bool closed = fade_animation_->GetCurrentValue() == 0; 189 bool closed = fade_animation_->GetCurrentValue() == 0;
119 fade_animation_->Reset(); 190 fade_animation_->Reset();
120 if (closed) 191 if (closed)
121 GetWidget()->Close(); 192 GetWidget()->Close();
122 } 193 }
123 194
124 void BubbleDelegateView::AnimationProgressed(const ui::Animation* animation) { 195 void BubbleDelegateView::AnimationProgressed(const ui::Animation* animation) {
125 DCHECK_EQ(animation, fade_animation_.get()); 196 DCHECK_EQ(animation, fade_animation_.get());
126 DCHECK(fade_animation_->is_animating()); 197 DCHECK(fade_animation_->is_animating());
127 GetWidget()->SetOpacity(fade_animation_->GetCurrentValue() * 255); 198 unsigned char opacity = fade_animation_->GetCurrentValue() * 255;
199 #if defined(OS_WIN) && !defined(USE_AURA)
200 // Explicitly set the content Widget's layered style and set transparency via
201 // SetLayeredWindowAttributes. This is done because initializing the Widget as
202 // transparent and setting opacity via UpdateLayeredWindow doesn't support
203 // hosting child native Windows controls.
204 const HWND hwnd = GetWidget()->GetNativeView();
205 const DWORD style = GetWindowLong(hwnd, GWL_EXSTYLE);
206 if ((opacity == 255) == !!(style & WS_EX_LAYERED))
207 SetWindowLong(hwnd, GWL_EXSTYLE, style ^ WS_EX_LAYERED);
208 SetLayeredWindowAttributes(hwnd, 0, opacity, LWA_ALPHA);
209 // Update the border widget's opacity.
210 border_widget_->SetOpacity(opacity);
211 border_widget_->non_client_view()->SchedulePaint();
212 #endif
213 GetWidget()->SetOpacity(opacity);
128 SchedulePaint(); 214 SchedulePaint();
129 } 215 }
130 216
131 const BubbleView* BubbleDelegateView::GetBubbleView() const { 217 BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
132 return GetWidget()->client_view()->AsBubbleView(); 218 const Widget* widget = border_widget_ ? border_widget_ : GetWidget();
133 } 219 return static_cast<BubbleFrameView*>(widget->non_client_view()->frame_view());
134
135 const BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
136 return static_cast<BubbleFrameView*>(
137 GetWidget()->non_client_view()->frame_view());
138 } 220 }
139 221
140 gfx::Rect BubbleDelegateView::GetBubbleBounds() { 222 gfx::Rect BubbleDelegateView::GetBubbleBounds() {
141 // The argument rect has its origin at the bubble's arrow anchor point; 223 // The argument rect has its origin at the bubble's arrow anchor point;
142 // its size is the preferred size of the bubble's client view (this view). 224 // its size is the preferred size of the bubble's client view (this view).
143 return GetBubbleFrameView()->GetWindowBoundsForClientBounds( 225 return GetBubbleFrameView()->GetWindowBoundsForClientBounds(
144 gfx::Rect(GetAnchorPoint(), GetPreferredSize())); 226 gfx::Rect(GetAnchorPoint(), GetPreferredSize()));
145 } 227 }
146 228
229 #if defined(OS_WIN) && !defined(USE_AURA)
230 void BubbleDelegateView::InitializeBorderWidget(Widget* parent_widget) {
231 border_widget_ = CreateBorderWidget(this, parent_widget);
232 border_widget_->SetBounds(GetBubbleBounds());
233 }
234
235 gfx::Rect BubbleDelegateView::GetBubbleClientBounds() const {
236 gfx::Rect client_bounds(GetBubbleFrameView()->GetBoundsForClientView());
237 client_bounds.Offset(border_widget_->GetWindowScreenBounds().origin());
238 return client_bounds;
239 }
240 #endif
241
147 } // namespace views 242 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698