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

Side by Side Diff: views/bubble/bubble_delegate.cc

Issue 8588064: views: Move bubble, events, focus and layout to ui/views/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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/bubble/bubble_delegate_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "views/bubble/bubble_delegate.h"
6
7 #include "ui/base/animation/slide_animation.h"
8 #include "views/bubble/bubble_frame_view.h"
9 #include "views/widget/widget.h"
10
11 // The duration of the fade animation in milliseconds.
12 static const int kHideFadeDurationMS = 200;
13
14 namespace views {
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 defined(OS_WIN) && !defined(USE_AURA)
26 bubble_params.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS;
27 bubble_params.transparent = false;
28 #endif
29 bubble_widget->Init(bubble_params);
30 return bubble_widget;
31 }
32
33 #if defined(OS_WIN) && !defined(USE_AURA)
34 // The border widget's delegate, needed for transparent Windows native controls.
35 // TODO(msw): Remove this when Windows native controls are no longer needed.
36 class VIEWS_EXPORT BubbleBorderDelegateView : public WidgetDelegateView {
37 public:
38 explicit BubbleBorderDelegateView(BubbleDelegateView* bubble)
39 : bubble_(bubble) {}
40 virtual ~BubbleBorderDelegateView() {}
41
42 // WidgetDelegateView overrides:
43 virtual bool CanActivate() const OVERRIDE;
44 virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE;
45
46 private:
47 BubbleDelegateView* bubble_;
48
49 DISALLOW_COPY_AND_ASSIGN(BubbleBorderDelegateView);
50 };
51
52 bool BubbleBorderDelegateView::CanActivate() const { return false; }
53
54 NonClientFrameView* BubbleBorderDelegateView::CreateNonClientFrameView() {
55 return bubble_->CreateNonClientFrameView();
56 }
57
58 // Create a widget to host the bubble's border.
59 Widget* CreateBorderWidget(BubbleDelegateView* bubble, Widget* parent) {
60 Widget* border_widget = new Widget();
61 Widget::InitParams border_params(Widget::InitParams::TYPE_BUBBLE);
62 border_params.delegate = new BubbleBorderDelegateView(bubble);
63 border_params.transparent = true;
64 border_params.parent_widget = parent;
65 if (!border_params.parent_widget)
66 border_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
67 border_widget->Init(border_params);
68 return border_widget;
69 }
70 #endif
71
72 } // namespace
73
74 BubbleDelegateView::BubbleDelegateView()
75 : close_on_esc_(true),
76 close_on_deactivate_(true),
77 allow_bubble_offscreen_(false),
78 anchor_view_(NULL),
79 arrow_location_(BubbleBorder::TOP_LEFT),
80 color_(SK_ColorWHITE),
81 border_widget_(NULL),
82 use_focusless_(false) {
83 set_background(views::Background::CreateSolidBackground(color_));
84 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, 0));
85 }
86
87 BubbleDelegateView::BubbleDelegateView(
88 View* anchor_view,
89 BubbleBorder::ArrowLocation arrow_location,
90 const SkColor& color)
91 : close_on_esc_(true),
92 close_on_deactivate_(true),
93 allow_bubble_offscreen_(false),
94 anchor_view_(anchor_view),
95 arrow_location_(arrow_location),
96 color_(color),
97 original_opacity_(255),
98 border_widget_(NULL),
99 use_focusless_(false) {
100 set_background(views::Background::CreateSolidBackground(color_));
101 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, 0));
102 }
103
104 BubbleDelegateView::~BubbleDelegateView() {
105 if (border_widget_)
106 border_widget_->Close();
107 }
108
109 // static
110 Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) {
111 bubble_delegate->Init();
112 Widget* parent = bubble_delegate->anchor_view() ?
113 bubble_delegate->anchor_view()->GetWidget() : NULL;
114 Widget* bubble_widget = CreateBubbleWidget(bubble_delegate, parent);
115
116 #if defined(OS_WIN) && !defined(USE_AURA)
117 // First set the contents view to initialize view bounds for widget sizing.
118 bubble_widget->SetContentsView(bubble_delegate->GetContentsView());
119 bubble_delegate->border_widget_ = CreateBorderWidget(bubble_delegate, parent);
120 #endif
121
122 bubble_delegate->SizeToContents();
123 bubble_widget->AddObserver(bubble_delegate);
124 if (parent && parent->GetTopLevelWidget())
125 parent->GetTopLevelWidget()->DisableInactiveRendering();
126 return bubble_widget;
127 }
128
129 View* BubbleDelegateView::GetInitiallyFocusedView() {
130 return this;
131 }
132
133 BubbleDelegateView* BubbleDelegateView::AsBubbleDelegate() {
134 return this;
135 }
136
137 View* BubbleDelegateView::GetContentsView() {
138 return this;
139 }
140
141 NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView() {
142 return new BubbleFrameView(GetArrowLocation(),
143 GetPreferredSize(),
144 GetColor(),
145 allow_bubble_offscreen_);
146 }
147
148 void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget,
149 bool active) {
150 if (close_on_deactivate() && widget == GetWidget() && !active) {
151 GetWidget()->RemoveObserver(this);
152 GetWidget()->Close();
153 }
154 }
155
156 gfx::Point BubbleDelegateView::GetAnchorPoint() {
157 if (!anchor_view())
158 return gfx::Point();
159
160 BubbleBorder::ArrowLocation location = GetArrowLocation();
161 gfx::Point anchor(anchor_view()->bounds().CenterPoint());
162 // By default, pick the middle of |anchor_view_|'s edge opposite the arrow.
163 if (BubbleBorder::is_arrow_on_horizontal(location)) {
164 anchor.SetPoint(anchor_view()->width() / 2,
165 BubbleBorder::is_arrow_on_top(location) ? anchor_view()->height() : 0);
166 } else if (BubbleBorder::has_arrow(location)) {
167 anchor.SetPoint(
168 BubbleBorder::is_arrow_on_left(location) ? anchor_view()->width() : 0,
169 anchor_view_->height() / 2);
170 }
171 View::ConvertPointToScreen(anchor_view(), &anchor);
172 return anchor;
173 }
174
175 BubbleBorder::ArrowLocation BubbleDelegateView::GetArrowLocation() const {
176 return arrow_location_;
177 }
178
179 SkColor BubbleDelegateView::GetColor() const {
180 return color_;
181 }
182
183 void BubbleDelegateView::Show() {
184 if (border_widget_)
185 border_widget_->Show();
186 GetWidget()->Show();
187 GetFocusManager()->SetFocusedView(GetInitiallyFocusedView());
188 }
189
190 void BubbleDelegateView::StartFade(bool fade_in) {
191 fade_animation_.reset(new ui::SlideAnimation(this));
192 fade_animation_->SetSlideDuration(kHideFadeDurationMS);
193 fade_animation_->Reset(fade_in ? 0.0 : 1.0);
194 if (fade_in) {
195 original_opacity_ = 0;
196 if (border_widget_)
197 border_widget_->SetOpacity(original_opacity_);
198 GetWidget()->SetOpacity(original_opacity_);
199 Show();
200 fade_animation_->Show();
201 } else {
202 original_opacity_ = 255;
203 fade_animation_->Hide();
204 }
205 }
206
207 void BubbleDelegateView::ResetFade() {
208 fade_animation_.reset();
209 if (border_widget_)
210 border_widget_->SetOpacity(original_opacity_);
211 GetWidget()->SetOpacity(original_opacity_);
212 }
213
214 bool BubbleDelegateView::AcceleratorPressed(
215 const ui::Accelerator& accelerator) {
216 if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
217 return false;
218 if (fade_animation_.get())
219 fade_animation_->Reset();
220 GetWidget()->Close();
221 return true;
222 }
223
224 void BubbleDelegateView::AnimationEnded(const ui::Animation* animation) {
225 if (animation != fade_animation_.get())
226 return;
227 bool closed = fade_animation_->GetCurrentValue() == 0;
228 fade_animation_->Reset();
229 if (closed)
230 GetWidget()->Close();
231 }
232
233 void BubbleDelegateView::AnimationProgressed(const ui::Animation* animation) {
234 if (animation != fade_animation_.get())
235 return;
236 DCHECK(fade_animation_->is_animating());
237 unsigned char opacity = fade_animation_->GetCurrentValue() * 255;
238 #if defined(OS_WIN) && !defined(USE_AURA)
239 // Explicitly set the content Widget's layered style and set transparency via
240 // SetLayeredWindowAttributes. This is done because initializing the Widget as
241 // transparent and setting opacity via UpdateLayeredWindow doesn't support
242 // hosting child native Windows controls.
243 const HWND hwnd = GetWidget()->GetNativeView();
244 const DWORD style = GetWindowLong(hwnd, GWL_EXSTYLE);
245 if ((opacity == 255) == !!(style & WS_EX_LAYERED))
246 SetWindowLong(hwnd, GWL_EXSTYLE, style ^ WS_EX_LAYERED);
247 SetLayeredWindowAttributes(hwnd, 0, opacity, LWA_ALPHA);
248 // Update the border widget's opacity.
249 border_widget_->SetOpacity(opacity);
250 border_widget_->non_client_view()->SchedulePaint();
251 #endif
252 GetWidget()->SetOpacity(opacity);
253 SchedulePaint();
254 }
255
256 void BubbleDelegateView::Init() {}
257
258 void BubbleDelegateView::SizeToContents() {
259 #if defined(OS_WIN) && !defined(USE_AURA)
260 border_widget_->SetBounds(GetBubbleBounds());
261 GetWidget()->SetBounds(GetBubbleClientBounds());
262 #else
263 GetWidget()->SetBounds(GetBubbleBounds());
264 #endif
265 }
266
267 BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
268 const Widget* widget = border_widget_ ? border_widget_ : GetWidget();
269 return static_cast<BubbleFrameView*>(widget->non_client_view()->frame_view());
270 }
271
272 gfx::Rect BubbleDelegateView::GetBubbleBounds() {
273 // The argument rect has its origin at the bubble's arrow anchor point;
274 // its size is the preferred size of the bubble's client view (this view).
275 return GetBubbleFrameView()->GetWindowBoundsForClientBounds(
276 gfx::Rect(GetAnchorPoint(), GetPreferredSize()));
277 }
278
279 #if defined(OS_WIN) && !defined(USE_AURA)
280 gfx::Rect BubbleDelegateView::GetBubbleClientBounds() const {
281 gfx::Rect client_bounds(GetBubbleFrameView()->GetBoundsForClientView());
282 client_bounds.Offset(border_widget_->GetWindowScreenBounds().origin());
283 return client_bounds;
284 }
285 #endif
286
287 } // namespace views
OLDNEW
« no previous file with comments | « views/bubble/bubble_delegate.h ('k') | views/bubble/bubble_delegate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698