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

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: Cleanup changes, remove example test code. 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
« no previous file with comments | « views/bubble/bubble_delegate.h ('k') | views/examples/bubble_example.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {}
Ben Goodger (Google) 2011/10/27 15:37:00 nit: 4-space indent instead of 2.
msw 2011/10/28 17:10:18 Done.
42 virtual ~BubbleBorderDelegateView() {}
43
44 // WidgetDelegateView overrides:
45 virtual bool CanActivate() const OVERRIDE { return false; }
46 virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE {
47 return bubble_->CreateNonClientFrameView();
48 }
49
50 private:
51 BubbleDelegateView* bubble_;
52
53 DISALLOW_COPY_AND_ASSIGN(BubbleBorderDelegateView);
54 };
55
56 // Create a widget to host the bubble's border.
57 Widget* CreateBorderWidget(BubbleDelegateView* bubble, Widget* parent) {
58 Widget* border_widget = new Widget();
59 Widget::InitParams border_params(Widget::InitParams::TYPE_BUBBLE);
60 border_params.delegate = new BubbleBorderDelegateView(bubble);
61 border_params.transparent = true;
62 border_params.parent_widget = parent;
63 if (!border_params.parent_widget)
64 border_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
65 border_widget->Init(border_params);
66 return border_widget;
67 }
68 #endif
69
70 } // namespace
71
16 BubbleDelegateView::BubbleDelegateView() 72 BubbleDelegateView::BubbleDelegateView()
17 : WidgetDelegateView(), 73 : close_on_esc_(true),
18 close_on_esc_(true),
19 arrow_location_(BubbleBorder::TOP_LEFT), 74 arrow_location_(BubbleBorder::TOP_LEFT),
20 color_(SK_ColorWHITE) { 75 color_(SK_ColorWHITE),
76 border_widget_(NULL) {
77 set_background(views::Background::CreateSolidBackground(color_));
21 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0)); 78 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0));
22 } 79 }
23 80
24 BubbleDelegateView::BubbleDelegateView( 81 BubbleDelegateView::BubbleDelegateView(
25 const gfx::Point& anchor_point, 82 const gfx::Point& anchor_point,
26 BubbleBorder::ArrowLocation arrow_location, 83 BubbleBorder::ArrowLocation arrow_location,
27 const SkColor& color) 84 const SkColor& color)
28 : WidgetDelegateView(), 85 : close_on_esc_(true),
29 close_on_esc_(true),
30 anchor_point_(anchor_point), 86 anchor_point_(anchor_point),
31 arrow_location_(arrow_location), 87 arrow_location_(arrow_location),
32 color_(color) { 88 color_(color),
89 border_widget_(NULL) {
90 set_background(views::Background::CreateSolidBackground(color_));
33 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0)); 91 AddAccelerator(Accelerator(ui::VKEY_ESCAPE, 0));
34 } 92 }
35 93
36 BubbleDelegateView::~BubbleDelegateView() {} 94 BubbleDelegateView::~BubbleDelegateView() {
95 if (border_widget_)
96 border_widget_->Close();
97 }
37 98
38 // static 99 // static
39 Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate, 100 Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate,
40 Widget* parent_widget) { 101 Widget* parent_widget) {
41 bubble_delegate->Init(); 102 bubble_delegate->Init();
42 views::Widget* bubble_widget = new views::Widget(); 103 Widget* bubble_widget = CreateBubbleWidget(bubble_delegate, parent_widget);
43 views::Widget::InitParams params(views::Widget::InitParams::TYPE_BUBBLE); 104
44 params.delegate = bubble_delegate; 105 #if defined(OS_WIN) && !defined(USE_AURA)
45 params.transparent = true; 106 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
46 if (!parent_widget) 107 bubble_delegate->border_widget_ = border_widget;
47 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 108 bubble_widget->SetContentsView(bubble_delegate->GetContentsView());
48 params.parent_widget = parent_widget; 109 border_widget->SetBounds(bubble_delegate->GetBubbleBounds());
49 bubble_widget->Init(params); 110 gfx::Rect client_bounds(
111 bubble_delegate->GetBubbleFrameView()->GetBoundsForClientView());
112 client_bounds.Offset(border_widget->GetWindowScreenBounds().origin());
113 bubble_widget->SetBounds(client_bounds);
114 #else
50 bubble_widget->SetBounds(bubble_delegate->GetBubbleBounds()); 115 bubble_widget->SetBounds(bubble_delegate->GetBubbleBounds());
116 #endif
117
51 return bubble_widget; 118 return bubble_widget;
52 } 119 }
53 120
54 View* BubbleDelegateView::GetInitiallyFocusedView() { 121 View* BubbleDelegateView::GetInitiallyFocusedView() {
55 return this; 122 return this;
56 } 123 }
57 124
58 View* BubbleDelegateView::GetContentsView() { 125 View* BubbleDelegateView::GetContentsView() {
59 return this; 126 return this;
60 } 127 }
61 128
62 ClientView* BubbleDelegateView::CreateClientView(Widget* widget) {
63 return new ClientView(widget, GetContentsView());
64 }
65
66 NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView() { 129 NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView() {
67 return new BubbleFrameView(GetArrowLocation(), 130 return new BubbleFrameView(GetArrowLocation(),
68 GetPreferredSize(), 131 GetPreferredSize(),
69 GetColor()); 132 GetColor());
70 } 133 }
71 134
72 gfx::Point BubbleDelegateView::GetAnchorPoint() { 135 gfx::Point BubbleDelegateView::GetAnchorPoint() {
73 return anchor_point_; 136 return anchor_point_;
74 } 137 }
75 138
76 BubbleBorder::ArrowLocation BubbleDelegateView::GetArrowLocation() const { 139 BubbleBorder::ArrowLocation BubbleDelegateView::GetArrowLocation() const {
77 return arrow_location_; 140 return arrow_location_;
78 } 141 }
79 142
80 SkColor BubbleDelegateView::GetColor() const { 143 SkColor BubbleDelegateView::GetColor() const {
81 return color_; 144 return color_;
82 } 145 }
83 146
84 void BubbleDelegateView::Init() {} 147 void BubbleDelegateView::Show() {
148 if (border_widget_)
149 border_widget_->Show();
150 GetWidget()->Show();
151 GetFocusManager()->SetFocusedView(GetInitiallyFocusedView());
152 }
85 153
86 void BubbleDelegateView::StartFade(bool fade_in) { 154 void BubbleDelegateView::StartFade(bool fade_in) {
87 fade_animation_.reset(new ui::SlideAnimation(this)); 155 fade_animation_.reset(new ui::SlideAnimation(this));
88 fade_animation_->SetSlideDuration(kHideFadeDurationMS); 156 fade_animation_->SetSlideDuration(kHideFadeDurationMS);
89 fade_animation_->Reset(fade_in ? 0.0 : 1.0); 157 fade_animation_->Reset(fade_in ? 0.0 : 1.0);
158
159 #if defined(OS_WIN) && !defined(USE_AURA)
160 HWND hwnd = GetWidget()->GetNativeView();
161 SetWindowLong(hwnd, GWL_EXSTYLE,
162 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
163 #endif
164
90 if (fade_in) { 165 if (fade_in) {
166 if (border_widget_)
167 border_widget_->SetOpacity(0);
91 GetWidget()->SetOpacity(0); 168 GetWidget()->SetOpacity(0);
92 GetWidget()->Show(); 169 Show();
93 fade_animation_->Show(); 170 fade_animation_->Show();
94 } else { 171 } else {
95 fade_animation_->Hide(); 172 fade_animation_->Hide();
96 } 173 }
97 } 174 }
98 175
99 bool BubbleDelegateView::AcceleratorPressed(const Accelerator& accelerator) { 176 bool BubbleDelegateView::AcceleratorPressed(const Accelerator& accelerator) {
100 if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE) 177 if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
101 return false; 178 return false;
102 if (fade_animation_.get()) 179 if (fade_animation_.get())
103 fade_animation_->Reset(); 180 fade_animation_->Reset();
104 GetWidget()->Close(); 181 GetWidget()->Close();
105 return true; 182 return true;
106 } 183 }
107 184
185 void BubbleDelegateView::Init() {}
186
108 void BubbleDelegateView::AnimationEnded(const ui::Animation* animation) { 187 void BubbleDelegateView::AnimationEnded(const ui::Animation* animation) {
109 DCHECK_EQ(animation, fade_animation_.get()); 188 DCHECK_EQ(animation, fade_animation_.get());
110 bool closed = fade_animation_->GetCurrentValue() == 0; 189 bool closed = fade_animation_->GetCurrentValue() == 0;
111 fade_animation_->Reset(); 190 fade_animation_->Reset();
191
192 #if defined(OS_WIN) && !defined(USE_AURA)
193 HWND hwnd = GetWidget()->GetNativeView();
194 SetWindowLong(hwnd, GWL_EXSTYLE,
195 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.
196 #endif
197
112 if (closed) 198 if (closed)
113 GetWidget()->Close(); 199 GetWidget()->Close();
114 } 200 }
115 201
116 void BubbleDelegateView::AnimationProgressed(const ui::Animation* animation) { 202 void BubbleDelegateView::AnimationProgressed(const ui::Animation* animation) {
117 DCHECK_EQ(animation, fade_animation_.get()); 203 DCHECK_EQ(animation, fade_animation_.get());
118 DCHECK(fade_animation_->is_animating()); 204 DCHECK(fade_animation_->is_animating());
119 GetWidget()->SetOpacity(fade_animation_->GetCurrentValue() * 255); 205 unsigned char opacity = fade_animation_->GetCurrentValue() * 255;
206 #if defined(OS_WIN) && !defined(USE_AURA)
207 HWND hwnd = GetWidget()->GetNativeView();
208 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
209 border_widget_->SetOpacity(opacity);
210 border_widget_->non_client_view()->SchedulePaint();
211 #endif
212 GetWidget()->SetOpacity(opacity);
120 SchedulePaint(); 213 SchedulePaint();
121 } 214 }
122 215
123 const BubbleView* BubbleDelegateView::GetBubbleView() const { 216 const BubbleView* BubbleDelegateView::GetBubbleView() const {
124 return GetWidget()->client_view()->AsBubbleView(); 217 return GetWidget()->client_view()->AsBubbleView();
125 } 218 }
126 219
127 const BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const { 220 const BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
128 return static_cast<BubbleFrameView*>( 221 return static_cast<BubbleFrameView*>(
222 #if defined(OS_WIN) && !defined(USE_AURA)
223 border_widget_->non_client_view()->frame_view());
224 #else
129 GetWidget()->non_client_view()->frame_view()); 225 GetWidget()->non_client_view()->frame_view());
226 #endif
130 } 227 }
131 228
132 gfx::Rect BubbleDelegateView::GetBubbleBounds() { 229 gfx::Rect BubbleDelegateView::GetBubbleBounds() {
133 // The argument rect has its origin at the bubble's arrow anchor point; 230 // The argument rect has its origin at the bubble's arrow anchor point;
134 // its size is the preferred size of the bubble's client view (this view). 231 // its size is the preferred size of the bubble's client view (this view).
135 return GetBubbleFrameView()->GetWindowBoundsForClientBounds( 232 return GetBubbleFrameView()->GetWindowBoundsForClientBounds(
136 gfx::Rect(GetAnchorPoint(), GetPreferredSize())); 233 gfx::Rect(GetAnchorPoint(), GetPreferredSize()));
137 } 234 }
138 235
139 } // namespace views 236 } // namespace views
OLDNEW
« no previous file with comments | « views/bubble/bubble_delegate.h ('k') | views/examples/bubble_example.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698