OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "ash/wm/caption_buttons/frame_caption_button_container_view.h" | 5 #include "ash/wm/caption_buttons/frame_caption_button_container_view.h" |
6 | 6 |
7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
8 #include "ash/metrics/user_metrics_recorder.h" | 8 #include "ash/metrics/user_metrics_recorder.h" |
9 #include "ash/shell.h" | 9 #include "ash/shell.h" |
10 #include "ash/wm/caption_buttons/alternate_frame_size_button.h" | 10 #include "ash/wm/caption_buttons/alternate_frame_size_button.h" |
11 #include "ash/wm/caption_buttons/frame_caption_button.h" | 11 #include "ash/wm/caption_buttons/frame_caption_button.h" |
12 #include "ash/wm/caption_buttons/frame_maximize_button.h" | 12 #include "ash/wm/caption_buttons/frame_maximize_button.h" |
13 #include "grit/ash_resources.h" | |
14 #include "grit/ui_strings.h" // Accessibility names | 13 #include "grit/ui_strings.h" // Accessibility names |
15 #include "ui/base/hit_test.h" | 14 #include "ui/base/hit_test.h" |
16 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
17 #include "ui/base/resource/resource_bundle.h" | |
18 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | 16 #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
19 #include "ui/gfx/canvas.h" | 17 #include "ui/gfx/canvas.h" |
20 #include "ui/gfx/insets.h" | 18 #include "ui/gfx/insets.h" |
21 #include "ui/gfx/point.h" | 19 #include "ui/gfx/point.h" |
22 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
23 #include "ui/views/widget/widget_delegate.h" | 21 #include "ui/views/widget/widget_delegate.h" |
24 | 22 |
25 namespace ash { | 23 namespace ash { |
26 | 24 |
27 namespace { | 25 namespace { |
28 | 26 |
29 // The distance between buttons. | |
30 const int kDistanceBetweenButtons = -1; | |
James Cook
2014/02/03 18:46:35
Hooray, no more crazy overlap constant!
| |
31 | |
32 // Converts |point| from |src| to |dst| and hittests against |dst|. | 27 // Converts |point| from |src| to |dst| and hittests against |dst|. |
33 bool ConvertPointToViewAndHitTest(const views::View* src, | 28 bool ConvertPointToViewAndHitTest(const views::View* src, |
34 const views::View* dst, | 29 const views::View* dst, |
35 const gfx::Point& point) { | 30 const gfx::Point& point) { |
36 gfx::Point converted(point); | 31 gfx::Point converted(point); |
37 views::View::ConvertPointToTarget(src, dst, &converted); | 32 views::View::ConvertPointToTarget(src, dst, &converted); |
38 return dst->HitTestPoint(converted); | 33 return dst->HitTestPoint(converted); |
39 } | 34 } |
40 | 35 |
41 } // namespace | 36 } // namespace |
(...skipping 28 matching lines...) Expand all Loading... | |
70 size_button_ = new FrameMaximizeButton(this, frame); | 65 size_button_ = new FrameMaximizeButton(this, frame); |
71 size_button_->SetAccessibleName( | 66 size_button_->SetAccessibleName( |
72 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE)); | 67 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE)); |
73 size_button_->SetVisible(frame_->widget_delegate()->CanMaximize()); | 68 size_button_->SetVisible(frame_->widget_delegate()->CanMaximize()); |
74 AddChildView(size_button_); | 69 AddChildView(size_button_); |
75 | 70 |
76 close_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_CLOSE); | 71 close_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_CLOSE); |
77 close_button_->SetAccessibleName( | 72 close_button_->SetAccessibleName( |
78 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE)); | 73 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE)); |
79 AddChildView(close_button_); | 74 AddChildView(close_button_); |
80 | |
81 button_separator_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
82 IDR_AURA_WINDOW_BUTTON_SEPARATOR).AsImageSkia(); | |
83 } | 75 } |
84 | 76 |
85 FrameCaptionButtonContainerView::~FrameCaptionButtonContainerView() { | 77 FrameCaptionButtonContainerView::~FrameCaptionButtonContainerView() { |
86 } | 78 } |
87 | 79 |
88 FrameMaximizeButton* | 80 FrameMaximizeButton* |
89 FrameCaptionButtonContainerView::GetOldStyleSizeButton() { | 81 FrameCaptionButtonContainerView::GetOldStyleSizeButton() { |
90 return switches::UseAlternateFrameCaptionButtonStyle() ? | 82 return switches::UseAlternateFrameCaptionButtonStyle() ? |
91 NULL : static_cast<FrameMaximizeButton*>(size_button_); | 83 NULL : static_cast<FrameMaximizeButton*>(size_button_); |
92 } | 84 } |
93 | 85 |
94 void FrameCaptionButtonContainerView::SetButtonImages(CaptionButtonIcon icon, | 86 void FrameCaptionButtonContainerView::SetButtonImages( |
95 int normal_image_id, | 87 CaptionButtonIcon icon, |
96 int hovered_image_id, | 88 int icon_image_id, |
97 int pressed_image_id) { | 89 int inactive_icon_image_id, |
98 button_icon_id_map_[icon] = ButtonIconIds(normal_image_id, | 90 int hovered_background_image_id, |
99 hovered_image_id, | 91 int pressed_background_image_id) { |
100 pressed_image_id); | 92 button_icon_id_map_[icon] = ButtonIconIds(icon_image_id, |
93 inactive_icon_image_id, | |
94 hovered_background_image_id, | |
95 pressed_background_image_id); | |
101 FrameCaptionButton* buttons[] = { | 96 FrameCaptionButton* buttons[] = { |
102 minimize_button_, size_button_, close_button_ | 97 minimize_button_, size_button_, close_button_ |
103 }; | 98 }; |
104 for (size_t i = 0; i < arraysize(buttons); ++i) { | 99 for (size_t i = 0; i < arraysize(buttons); ++i) { |
105 if (buttons[i]->icon() == icon) { | 100 if (buttons[i]->icon() == icon) { |
106 buttons[i]->SetImages(icon, | 101 buttons[i]->SetImages(icon, |
107 FrameCaptionButton::ANIMATE_NO, | 102 FrameCaptionButton::ANIMATE_NO, |
108 normal_image_id, | 103 icon_image_id, |
109 hovered_image_id, | 104 inactive_icon_image_id, |
110 pressed_image_id); | 105 hovered_background_image_id, |
106 pressed_background_image_id); | |
111 } | 107 } |
112 } | 108 } |
113 } | 109 } |
114 | 110 |
111 void FrameCaptionButtonContainerView::SetPaintAsActive(bool paint_as_active) { | |
112 minimize_button_->set_paint_as_active(paint_as_active); | |
113 size_button_->set_paint_as_active(paint_as_active); | |
114 close_button_->set_paint_as_active(paint_as_active); | |
115 } | |
116 | |
115 void FrameCaptionButtonContainerView::ResetWindowControls() { | 117 void FrameCaptionButtonContainerView::ResetWindowControls() { |
116 SetButtonsToNormal(ANIMATE_NO); | 118 SetButtonsToNormal(ANIMATE_NO); |
117 } | 119 } |
118 | 120 |
119 int FrameCaptionButtonContainerView::NonClientHitTest( | 121 int FrameCaptionButtonContainerView::NonClientHitTest( |
120 const gfx::Point& point) const { | 122 const gfx::Point& point) const { |
121 if (close_button_->visible() && | 123 if (close_button_->visible() && |
122 ConvertPointToViewAndHitTest(this, close_button_, point)) { | 124 ConvertPointToViewAndHitTest(this, close_button_, point)) { |
123 return HTCLOSE; | 125 return HTCLOSE; |
124 } else if (size_button_->visible() && | 126 } else if (size_button_->visible() && |
125 ConvertPointToViewAndHitTest(this, size_button_, point)) { | 127 ConvertPointToViewAndHitTest(this, size_button_, point)) { |
126 return HTMAXBUTTON; | 128 return HTMAXBUTTON; |
127 } else if (minimize_button_->visible() && | 129 } else if (minimize_button_->visible() && |
128 ConvertPointToViewAndHitTest(this, minimize_button_, point)) { | 130 ConvertPointToViewAndHitTest(this, minimize_button_, point)) { |
129 return HTMINBUTTON; | 131 return HTMINBUTTON; |
130 } | 132 } |
131 return HTNOWHERE; | 133 return HTNOWHERE; |
132 } | 134 } |
133 | 135 |
134 gfx::Size FrameCaptionButtonContainerView::GetPreferredSize() { | 136 gfx::Size FrameCaptionButtonContainerView::GetPreferredSize() { |
135 int width = 0; | 137 int width = 0; |
136 bool first_visible = true; | |
137 for (int i = 0; i < child_count(); ++i) { | 138 for (int i = 0; i < child_count(); ++i) { |
138 views::View* child = child_at(i); | 139 views::View* child = child_at(i); |
139 if (!child->visible()) | 140 if (child->visible()) |
140 continue; | 141 width += child_at(i)->GetPreferredSize().width(); |
141 | |
142 width += child_at(i)->GetPreferredSize().width(); | |
143 if (!first_visible) | |
144 width += kDistanceBetweenButtons; | |
145 first_visible = false; | |
146 } | 142 } |
147 return gfx::Size(width, close_button_->GetPreferredSize().height()); | 143 return gfx::Size(width, close_button_->GetPreferredSize().height()); |
148 } | 144 } |
149 | 145 |
150 void FrameCaptionButtonContainerView::Layout() { | 146 void FrameCaptionButtonContainerView::Layout() { |
151 int x = 0; | 147 int x = 0; |
152 for (int i = 0; i < child_count(); ++i) { | 148 for (int i = 0; i < child_count(); ++i) { |
153 views::View* child = child_at(i); | 149 views::View* child = child_at(i); |
154 if (!child->visible()) | 150 if (!child->visible()) |
155 continue; | 151 continue; |
156 | 152 |
157 gfx::Size size = child->GetPreferredSize(); | 153 gfx::Size size = child->GetPreferredSize(); |
158 child->SetBounds(x, 0, size.width(), size.height()); | 154 child->SetBounds(x, 0, size.width(), size.height()); |
159 x += size.width() + kDistanceBetweenButtons; | 155 x += size.width(); |
160 } | 156 } |
161 } | 157 } |
162 | 158 |
163 const char* FrameCaptionButtonContainerView::GetClassName() const { | 159 const char* FrameCaptionButtonContainerView::GetClassName() const { |
164 return kViewClassName; | 160 return kViewClassName; |
165 } | 161 } |
166 | 162 |
167 void FrameCaptionButtonContainerView::OnPaint(gfx::Canvas* canvas) { | |
168 views::View::OnPaint(canvas); | |
169 | |
170 // The alternate button style does not paint the button separator. | |
171 if (!switches::UseAlternateFrameCaptionButtonStyle()) { | |
172 // We should have at most two visible buttons. The button separator is | |
173 // always painted underneath the close button regardless of whether a | |
174 // button other than the close button is visible. | |
175 gfx::Rect divider(close_button_->bounds().origin(), | |
176 button_separator_.size()); | |
177 canvas->DrawImageInt(button_separator_, | |
178 GetMirroredXForRect(divider), | |
179 divider.y()); | |
180 } | |
181 } | |
182 | |
183 void FrameCaptionButtonContainerView::SetButtonIcon(FrameCaptionButton* button, | 163 void FrameCaptionButtonContainerView::SetButtonIcon(FrameCaptionButton* button, |
184 CaptionButtonIcon icon, | 164 CaptionButtonIcon icon, |
185 Animate animate) { | 165 Animate animate) { |
186 if (button->icon() == icon && | 166 if (button->icon() == icon && |
187 (animate == ANIMATE_YES || !button->is_animating_image_swap())) { | 167 (animate == ANIMATE_YES || !button->is_animating_image_swap())) { |
188 return; | 168 return; |
189 } | 169 } |
190 | 170 |
191 FrameCaptionButton::Animate fcb_animate = (animate == ANIMATE_YES) ? | 171 FrameCaptionButton::Animate fcb_animate = (animate == ANIMATE_YES) ? |
192 FrameCaptionButton::ANIMATE_YES : FrameCaptionButton::ANIMATE_NO; | 172 FrameCaptionButton::ANIMATE_YES : FrameCaptionButton::ANIMATE_NO; |
193 std::map<CaptionButtonIcon, ButtonIconIds>::const_iterator it = | 173 std::map<CaptionButtonIcon, ButtonIconIds>::const_iterator it = |
194 button_icon_id_map_.find(icon); | 174 button_icon_id_map_.find(icon); |
195 if (it != button_icon_id_map_.end()) { | 175 if (it != button_icon_id_map_.end()) { |
196 button->SetImages(icon, | 176 button->SetImages(icon, |
197 fcb_animate, | 177 fcb_animate, |
198 it->second.normal_image_id, | 178 it->second.icon_image_id, |
199 it->second.hovered_image_id, | 179 it->second.inactive_icon_image_id, |
200 it->second.pressed_image_id); | 180 it->second.hovered_background_image_id, |
181 it->second.pressed_background_image_id); | |
201 } | 182 } |
202 } | 183 } |
203 | 184 |
204 void FrameCaptionButtonContainerView::ButtonPressed(views::Button* sender, | 185 void FrameCaptionButtonContainerView::ButtonPressed(views::Button* sender, |
205 const ui::Event& event) { | 186 const ui::Event& event) { |
206 // When shift-clicking, slow down animations for visual debugging. | 187 // When shift-clicking, slow down animations for visual debugging. |
207 // We used to do this via an event filter that looked for the shift key being | 188 // We used to do this via an event filter that looked for the shift key being |
208 // pressed but this interfered with several normal keyboard shortcuts. | 189 // pressed but this interfered with several normal keyboard shortcuts. |
209 scoped_ptr<ui::ScopedAnimationDurationScaleMode> slow_duration_mode; | 190 scoped_ptr<ui::ScopedAnimationDurationScaleMode> slow_duration_mode; |
210 if (event.IsShiftDown()) { | 191 if (event.IsShiftDown()) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 if (!button->visible()) | 257 if (!button->visible()) |
277 continue; | 258 continue; |
278 | 259 |
279 if (button->state() == views::Button::STATE_PRESSED) { | 260 if (button->state() == views::Button::STATE_PRESSED) { |
280 gfx::Rect expanded_bounds = button->bounds(); | 261 gfx::Rect expanded_bounds = button->bounds(); |
281 expanded_bounds.Inset(pressed_hittest_outer_insets); | 262 expanded_bounds.Inset(pressed_hittest_outer_insets); |
282 if (expanded_bounds.Contains(position)) { | 263 if (expanded_bounds.Contains(position)) { |
283 pressed_button = button; | 264 pressed_button = button; |
284 // Do not break in order to give preference to buttons which are | 265 // Do not break in order to give preference to buttons which are |
285 // closer to |position_in_screen| than the currently pressed button. | 266 // closer to |position_in_screen| than the currently pressed button. |
286 // TODO(pkotwicz): Make the caption buttons not overlap. | |
287 } | 267 } |
288 } else if (ConvertPointToViewAndHitTest(this, button, position)) { | 268 } else if (ConvertPointToViewAndHitTest(this, button, position)) { |
289 pressed_button = button; | 269 pressed_button = button; |
290 break; | 270 break; |
291 } | 271 } |
292 } | 272 } |
293 | 273 |
294 for (size_t i = 0; i < arraysize(buttons); ++i) { | 274 for (size_t i = 0; i < arraysize(buttons); ++i) { |
295 buttons[i]->SetState(buttons[i] == pressed_button ? | 275 buttons[i]->SetState(buttons[i] == pressed_button ? |
296 views::Button::STATE_PRESSED : views::Button::STATE_NORMAL); | 276 views::Button::STATE_PRESSED : views::Button::STATE_NORMAL); |
297 } | 277 } |
298 return pressed_button; | 278 return pressed_button; |
299 } | 279 } |
300 | 280 |
301 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds() | 281 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds() |
302 : normal_image_id(-1), | 282 : icon_image_id(-1), |
303 hovered_image_id(-1), | 283 inactive_icon_image_id(-1), |
304 pressed_image_id(-1) { | 284 hovered_background_image_id(-1), |
285 pressed_background_image_id(-1) { | |
305 } | 286 } |
306 | 287 |
307 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds(int normal_id, | 288 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds( |
308 int hovered_id, | 289 int icon_id, |
309 int pressed_id) | 290 int inactive_icon_id, |
310 : normal_image_id(normal_id), | 291 int hovered_background_id, |
311 hovered_image_id(hovered_id), | 292 int pressed_background_id) |
312 pressed_image_id(pressed_id) { | 293 : icon_image_id(icon_id), |
294 inactive_icon_image_id(inactive_icon_id), | |
295 hovered_background_image_id(hovered_background_id), | |
296 pressed_background_image_id(pressed_background_id) { | |
313 } | 297 } |
314 | 298 |
315 FrameCaptionButtonContainerView::ButtonIconIds::~ButtonIconIds() { | 299 FrameCaptionButtonContainerView::ButtonIconIds::~ButtonIconIds() { |
316 } | 300 } |
317 | 301 |
318 } // namespace ash | 302 } // namespace ash |
OLD | NEW |