OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/ui/views/dropdown_bar_host.h" | 5 #include "chrome/browser/ui/views/dropdown_bar_host.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "chrome/browser/ui/view_ids.h" | 9 #include "chrome/browser/ui/view_ids.h" |
10 #include "chrome/browser/ui/views/dropdown_bar_host_delegate.h" | 10 #include "chrome/browser/ui/views/dropdown_bar_host_delegate.h" |
11 #include "chrome/browser/ui/views/dropdown_bar_view.h" | 11 #include "chrome/browser/ui/views/dropdown_bar_view.h" |
12 #include "chrome/browser/ui/views/frame/browser_view.h" | 12 #include "chrome/browser/ui/views/frame/browser_view.h" |
13 #include "ui/events/keycodes/keyboard_codes.h" | 13 #include "ui/events/keycodes/keyboard_codes.h" |
14 #include "ui/gfx/animation/slide_animation.h" | 14 #include "ui/gfx/animation/slide_animation.h" |
15 #include "ui/gfx/scrollbar_size.h" | 15 #include "ui/gfx/scrollbar_size.h" |
16 #include "ui/views/focus/external_focus_tracker.h" | 16 #include "ui/views/focus/external_focus_tracker.h" |
17 #include "ui/views/focus/view_storage.h" | 17 #include "ui/views/focus/view_storage.h" |
18 #include "ui/views/widget/widget.h" | 18 #include "ui/views/widget/widget.h" |
19 | 19 |
20 // static | 20 // static |
21 bool DropdownBarHost::disable_animations_during_testing_ = false; | 21 bool DropdownBarHost::disable_animations_during_testing_ = false; |
22 | 22 |
23 //////////////////////////////////////////////////////////////////////////////// | 23 //////////////////////////////////////////////////////////////////////////////// |
24 // DropdownBarHost, public: | 24 // DropdownBarHost, public: |
25 | 25 |
26 DropdownBarHost::DropdownBarHost(BrowserView* browser_view) | 26 DropdownBarHost::DropdownBarHost(BrowserView* browser_view) |
27 : browser_view_(browser_view), | 27 : browser_view_(browser_view), |
28 clip_view_(new views::View()), | |
29 view_(NULL), | 28 view_(NULL), |
30 delegate_(NULL), | 29 delegate_(NULL), |
| 30 animation_offset_(0), |
31 focus_manager_(NULL), | 31 focus_manager_(NULL), |
32 esc_accel_target_registered_(false), | 32 esc_accel_target_registered_(false), |
33 is_visible_(false) { | 33 is_visible_(false) { |
34 // The |clip_view_| must paint to a layer so that it can clip descendent Views | |
35 // which also paint to a Layer. | |
36 clip_view_->SetPaintToLayer(true); | |
37 clip_view_->SetFillsBoundsOpaquely(false); | |
38 clip_view_->layer()->SetMasksToBounds(true); | |
39 } | 34 } |
40 | 35 |
41 void DropdownBarHost::Init(views::View* host_view, | 36 void DropdownBarHost::Init(views::View* host_view, |
42 views::View* view, | 37 views::View* view, |
43 DropdownBarHostDelegate* delegate) { | 38 DropdownBarHostDelegate* delegate) { |
44 DCHECK(view); | 39 DCHECK(view); |
45 DCHECK(delegate); | 40 DCHECK(delegate); |
46 | 41 |
47 view_ = view; | 42 view_ = view; |
48 delegate_ = delegate; | 43 delegate_ = delegate; |
49 | 44 |
50 // Initialize the host. | 45 // Initialize the host. |
51 host_.reset(new views::Widget); | 46 host_.reset(new views::Widget); |
52 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); | 47 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); |
53 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 48 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
54 params.parent = browser_view_->GetWidget()->GetNativeView(); | 49 params.parent = browser_view_->GetWidget()->GetNativeView(); |
55 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 50 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
56 host_->Init(params); | 51 host_->Init(params); |
57 host_->SetContentsView(clip_view_); | 52 host_->SetContentsView(view_); |
58 clip_view_->AddChildView(view_); | |
59 | 53 |
60 SetHostViewNative(host_view); | 54 SetHostViewNative(host_view); |
61 | 55 |
62 // Start listening to focus changes, so we can register and unregister our | 56 // Start listening to focus changes, so we can register and unregister our |
63 // own handler for Escape. | 57 // own handler for Escape. |
64 focus_manager_ = host_->GetFocusManager(); | 58 focus_manager_ = host_->GetFocusManager(); |
65 if (focus_manager_) { | 59 if (focus_manager_) { |
66 focus_manager_->AddFocusChangeListener(this); | 60 focus_manager_->AddFocusChangeListener(this); |
67 } else { | 61 } else { |
68 // In some cases (see bug http://crbug.com/17056) it seems we may not have | 62 // In some cases (see bug http://crbug.com/17056) it seems we may not have |
69 // a focus manager. Please reopen the bug if you hit this. | 63 // a focus manager. Please reopen the bug if you hit this. |
70 NOTREACHED(); | 64 NOTREACHED(); |
71 } | 65 } |
72 | 66 |
| 67 // Start the process of animating the opening of the widget. |
73 animation_.reset(new gfx::SlideAnimation(this)); | 68 animation_.reset(new gfx::SlideAnimation(this)); |
74 // Update the widget and |view_| bounds to the hidden state. | |
75 AnimationProgressed(animation_.get()); | |
76 } | 69 } |
77 | 70 |
78 DropdownBarHost::~DropdownBarHost() { | 71 DropdownBarHost::~DropdownBarHost() { |
79 focus_manager_->RemoveFocusChangeListener(this); | 72 focus_manager_->RemoveFocusChangeListener(this); |
80 focus_tracker_.reset(NULL); | 73 focus_tracker_.reset(NULL); |
81 } | 74 } |
82 | 75 |
83 void DropdownBarHost::Show(bool animate) { | 76 void DropdownBarHost::Show(bool animate) { |
84 // Stores the currently focused view, and tracks focus changes so that we can | 77 // Stores the currently focused view, and tracks focus changes so that we can |
85 // restore focus when the dropdown widget is closed. | 78 // restore focus when the dropdown widget is closed. |
86 focus_tracker_.reset(new views::ExternalFocusTracker(view_, focus_manager_)); | 79 focus_tracker_.reset(new views::ExternalFocusTracker(view_, focus_manager_)); |
87 | 80 |
88 SetDialogPosition(GetDialogPosition(gfx::Rect())); | |
89 | |
90 host_->Show(); | |
91 | |
92 bool was_visible = is_visible_; | 81 bool was_visible = is_visible_; |
93 is_visible_ = true; | 82 is_visible_ = true; |
94 if (!animate || disable_animations_during_testing_) { | 83 if (!animate || disable_animations_during_testing_) { |
95 animation_->Reset(1); | 84 animation_->Reset(1); |
96 AnimationProgressed(animation_.get()); | 85 AnimationProgressed(animation_.get()); |
97 } else if (!was_visible) { | 86 } else if (!was_visible) { |
98 // Don't re-start the animation. | 87 // Don't re-start the animation. |
99 animation_->Reset(); | 88 animation_->Reset(); |
100 animation_->Show(); | 89 animation_->Show(); |
101 } | 90 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 } | 125 } |
137 | 126 |
138 void DropdownBarHost::StopAnimation() { | 127 void DropdownBarHost::StopAnimation() { |
139 animation_->End(); | 128 animation_->End(); |
140 } | 129 } |
141 | 130 |
142 bool DropdownBarHost::IsVisible() const { | 131 bool DropdownBarHost::IsVisible() const { |
143 return is_visible_; | 132 return is_visible_; |
144 } | 133 } |
145 | 134 |
146 void DropdownBarHost::SetDialogPosition(const gfx::Rect& new_pos) { | |
147 view_->SetSize(new_pos.size()); | |
148 | |
149 if (new_pos.IsEmpty()) | |
150 return; | |
151 | |
152 host()->SetBounds(new_pos); | |
153 } | |
154 | |
155 //////////////////////////////////////////////////////////////////////////////// | 135 //////////////////////////////////////////////////////////////////////////////// |
156 // DropdownBarHost, views::FocusChangeListener implementation: | 136 // DropdownBarHost, views::FocusChangeListener implementation: |
157 void DropdownBarHost::OnWillChangeFocus(views::View* focused_before, | 137 void DropdownBarHost::OnWillChangeFocus(views::View* focused_before, |
158 views::View* focused_now) { | 138 views::View* focused_now) { |
159 // First we need to determine if one or both of the views passed in are child | 139 // First we need to determine if one or both of the views passed in are child |
160 // views of our view. | 140 // views of our view. |
161 bool our_view_before = focused_before && view_->Contains(focused_before); | 141 bool our_view_before = focused_before && view_->Contains(focused_before); |
162 bool our_view_now = focused_now && view_->Contains(focused_now); | 142 bool our_view_now = focused_now && view_->Contains(focused_now); |
163 | 143 |
164 // When both our_view_before and our_view_now are false, it means focus is | 144 // When both our_view_before and our_view_now are false, it means focus is |
(...skipping 15 matching lines...) Expand all Loading... |
180 void DropdownBarHost::OnDidChangeFocus(views::View* focused_before, | 160 void DropdownBarHost::OnDidChangeFocus(views::View* focused_before, |
181 views::View* focused_now) { | 161 views::View* focused_now) { |
182 } | 162 } |
183 | 163 |
184 //////////////////////////////////////////////////////////////////////////////// | 164 //////////////////////////////////////////////////////////////////////////////// |
185 // DropdownBarHost, gfx::AnimationDelegate implementation: | 165 // DropdownBarHost, gfx::AnimationDelegate implementation: |
186 | 166 |
187 void DropdownBarHost::AnimationProgressed(const gfx::Animation* animation) { | 167 void DropdownBarHost::AnimationProgressed(const gfx::Animation* animation) { |
188 // First, we calculate how many pixels to slide the widget. | 168 // First, we calculate how many pixels to slide the widget. |
189 gfx::Size pref_size = view_->GetPreferredSize(); | 169 gfx::Size pref_size = view_->GetPreferredSize(); |
190 int view_offset = static_cast<int>((animation_->GetCurrentValue() - 1.0) * | 170 animation_offset_ = static_cast<int>((1.0 - animation_->GetCurrentValue()) * |
191 pref_size.height()); | 171 pref_size.height()); |
192 | 172 |
193 // This call makes sure |view_| appears in the right location, the size and | 173 // This call makes sure it appears in the right location, the size and shape |
194 // shape is correct and that it slides in the right direction. | 174 // is correct and that it slides in the right direction. |
195 view_->SetPosition(gfx::Point(0, view_offset)); | 175 gfx::Rect dlg_rect = GetDialogPosition(gfx::Rect()); |
| 176 SetDialogPosition(dlg_rect); |
| 177 |
| 178 // Let the view know if we are animating, and at which offset to draw the |
| 179 // edges. |
| 180 delegate_->SetAnimationOffset(animation_offset_); |
| 181 view_->SchedulePaint(); |
196 } | 182 } |
197 | 183 |
198 void DropdownBarHost::AnimationEnded(const gfx::Animation* animation) { | 184 void DropdownBarHost::AnimationEnded(const gfx::Animation* animation) { |
| 185 // Place the dropdown widget in its fully opened state. |
| 186 animation_offset_ = 0; |
| 187 |
199 if (!animation_->IsShowing()) { | 188 if (!animation_->IsShowing()) { |
200 // Animation has finished closing. | 189 // Animation has finished closing. |
201 host_->Hide(); | 190 host_->Hide(); |
202 is_visible_ = false; | 191 is_visible_ = false; |
203 OnVisibilityChanged(); | 192 OnVisibilityChanged(); |
204 } else { | 193 } else { |
205 // Animation has finished opening. | 194 // Animation has finished opening. |
206 } | 195 } |
207 } | 196 } |
208 | 197 |
(...skipping 19 matching lines...) Expand all Loading... |
228 escape, ui::AcceleratorManager::kNormalPriority, this); | 217 escape, ui::AcceleratorManager::kNormalPriority, this); |
229 esc_accel_target_registered_ = true; | 218 esc_accel_target_registered_ = true; |
230 } | 219 } |
231 | 220 |
232 void DropdownBarHost::UnregisterAccelerators() { | 221 void DropdownBarHost::UnregisterAccelerators() { |
233 DCHECK(esc_accel_target_registered_); | 222 DCHECK(esc_accel_target_registered_); |
234 ui::Accelerator escape(ui::VKEY_ESCAPE, ui::EF_NONE); | 223 ui::Accelerator escape(ui::VKEY_ESCAPE, ui::EF_NONE); |
235 focus_manager_->UnregisterAccelerator(escape, this); | 224 focus_manager_->UnregisterAccelerator(escape, this); |
236 esc_accel_target_registered_ = false; | 225 esc_accel_target_registered_ = false; |
237 } | 226 } |
OLD | NEW |