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