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

Side by Side Diff: ui/message_center/views/notifier_settings_view.cc

Issue 2300893002: Make notifier settings combobox a real combobox. (Closed)
Patch Set: remove dbg code Created 4 years, 3 months 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 "ui/message_center/views/notifier_settings_view.h" 5 #include "ui/message_center/views/notifier_settings_view.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/strings/string16.h" 14 #include "base/strings/string16.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "skia/ext/image_operations.h" 16 #include "skia/ext/image_operations.h"
17 #include "third_party/skia/include/core/SkColor.h" 17 #include "third_party/skia/include/core/SkColor.h"
18 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/models/simple_menu_model.h" 19 #include "ui/base/models/combobox_model.h"
20 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/events/event_utils.h" 21 #include "ui/events/event_utils.h"
22 #include "ui/events/keycodes/keyboard_codes.h" 22 #include "ui/events/keycodes/keyboard_codes.h"
23 #include "ui/gfx/canvas.h" 23 #include "ui/gfx/canvas.h"
24 #include "ui/gfx/geometry/size.h" 24 #include "ui/gfx/geometry/size.h"
25 #include "ui/gfx/image/image.h" 25 #include "ui/gfx/image/image.h"
26 #include "ui/message_center/message_center_style.h" 26 #include "ui/message_center/message_center_style.h"
27 #include "ui/message_center/views/message_center_view.h" 27 #include "ui/message_center/views/message_center_view.h"
28 #include "ui/resources/grit/ui_resources.h" 28 #include "ui/resources/grit/ui_resources.h"
29 #include "ui/strings/grit/ui_strings.h" 29 #include "ui/strings/grit/ui_strings.h"
30 #include "ui/views/background.h" 30 #include "ui/views/background.h"
31 #include "ui/views/border.h" 31 #include "ui/views/border.h"
32 #include "ui/views/controls/button/checkbox.h" 32 #include "ui/views/controls/button/checkbox.h"
33 #include "ui/views/controls/button/label_button_border.h" 33 #include "ui/views/controls/button/label_button_border.h"
34 #include "ui/views/controls/button/menu_button.h" 34 #include "ui/views/controls/combobox/combobox.h"
35 #include "ui/views/controls/image_view.h" 35 #include "ui/views/controls/image_view.h"
36 #include "ui/views/controls/label.h" 36 #include "ui/views/controls/label.h"
37 #include "ui/views/controls/link.h" 37 #include "ui/views/controls/link.h"
38 #include "ui/views/controls/link_listener.h" 38 #include "ui/views/controls/link_listener.h"
39 #include "ui/views/controls/menu/menu_runner.h"
40 #include "ui/views/controls/scroll_view.h" 39 #include "ui/views/controls/scroll_view.h"
41 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" 40 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
42 #include "ui/views/layout/box_layout.h" 41 #include "ui/views/layout/box_layout.h"
43 #include "ui/views/layout/fill_layout.h" 42 #include "ui/views/layout/fill_layout.h"
44 #include "ui/views/layout/grid_layout.h" 43 #include "ui/views/layout/grid_layout.h"
45 #include "ui/views/painter.h" 44 #include "ui/views/painter.h"
46 #include "ui/views/widget/widget.h" 45 #include "ui/views/widget/widget.h"
47 46
48 namespace message_center { 47 namespace message_center {
49 namespace settings { 48
49 namespace {
50 50
51 // Additional views-specific parameters. 51 // Additional views-specific parameters.
52 52
53 // The width of the settings pane in pixels. 53 // The width of the settings pane in pixels.
54 const int kWidth = 360; 54 const int kWidth = 360;
55 55
56 // The width of the learn more icon in pixels. 56 // The width of the learn more icon in pixels.
57 const int kLearnMoreSize = 12; 57 const int kLearnMoreSize = 12;
58 58
59 // The width of the click target that contains the learn more button in pixels. 59 // The width of the click target that contains the learn more button in pixels.
60 const int kLearnMoreTargetWidth = 28; 60 const int kLearnMoreTargetWidth = 28;
61 61
62 // The height of the click target that contains the learn more button in pixels. 62 // The height of the click target that contains the learn more button in pixels.
63 const int kLearnMoreTargetHeight = 40; 63 const int kLearnMoreTargetHeight = 40;
64 64
65 // The minimum height of the settings pane in pixels. 65 // The minimum height of the settings pane in pixels.
66 const int kMinimumHeight = 480; 66 const int kMinimumHeight = 480;
67 67
68 // The horizontal margin of the title area of the settings pane in addition to 68 // The horizontal margin of the title area of the settings pane in addition to
69 // the standard margin from settings::kHorizontalMargin. 69 // the standard margin from kHorizontalMargin.
70 const int kTitleMargin = 10; 70 const int kTitleMargin = 20;
71
72 } // namespace settings
73
74 namespace {
75
76 // Menu button metrics to make the text line up.
77 const int kMenuButtonInnateMargin = 2;
78
79 // Used to place the context menu correctly.
80 const int kMenuWhitespaceOffset = 2;
81 71
82 // The innate vertical blank space in the label for the title of the settings 72 // The innate vertical blank space in the label for the title of the settings
83 // pane. 73 // pane.
84 const int kInnateTitleBottomMargin = 1; 74 const int kInnateTitleBottomMargin = 1;
85 const int kInnateTitleTopMargin = 7; 75 const int kInnateTitleTopMargin = 7;
86 76
87 // The innate top blank space in the label for the description of the settings 77 // The innate top blank space in the label for the description of the settings
88 // pane. 78 // pane.
89 const int kInnateDescriptionTopMargin = 2; 79 const int kInnateDescriptionTopMargin = 2;
90 80
91 // Checkboxes have some built-in right padding blank space. 81 // Checkboxes have some built-in right padding blank space.
92 const int kInnateCheckboxRightPadding = 2; 82 const int kInnateCheckboxRightPadding = 2;
93 83
94 // Spec defines the checkbox size; the innate padding throws this measurement 84 // Spec defines the checkbox size; the innate padding throws this measurement
95 // off so we need to compute a slightly different area for the checkbox to 85 // off so we need to compute a slightly different area for the checkbox to
96 // inhabit. 86 // inhabit.
97 const int kComputedCheckboxSize = 87 const int kComputedCheckboxSize =
98 settings::kCheckboxSizeWithPadding - kInnateCheckboxRightPadding; 88 settings::kCheckboxSizeWithPadding - kInnateCheckboxRightPadding;
99 89
100 // The menubutton has innate margin, so we need to compensate for that when
101 // figuring the margin of the title area.
102 const int kComputedContentsTitleMargin = 0 - kMenuButtonInnateMargin;
103
104 // The spec doesn't include the bottom blank area of the title bar or the innate 90 // The spec doesn't include the bottom blank area of the title bar or the innate
105 // blank area in the description label, so we'll use this as the space between 91 // blank area in the description label, so we'll use this as the space between
106 // the title and description. 92 // the title and description.
107 const int kComputedTitleBottomMargin = settings::kDescriptionToSwitcherSpace - 93 const int kComputedTitleBottomMargin = settings::kDescriptionToSwitcherSpace -
108 kInnateTitleBottomMargin - 94 kInnateTitleBottomMargin -
109 kInnateDescriptionTopMargin; 95 kInnateDescriptionTopMargin;
110 96
111 // The blank space above the title needs to be adjusted by the amount of blank 97 // The blank space above the title needs to be adjusted by the amount of blank
112 // space included in the title label. 98 // space included in the title label.
113 const int kComputedTitleTopMargin = 99 const int kComputedTitleTopMargin =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 views::View* content = child_at(0); 147 views::View* content = child_at(0);
162 int content_width = width(); 148 int content_width = width();
163 int content_height = content->GetHeightForWidth(content_width); 149 int content_height = content->GetHeightForWidth(content_width);
164 int y = std::max((height() - content_height) / 2, 0); 150 int y = std::max((height() - content_height) / 2, 0);
165 content->SetBounds(0, y, content_width, content_height); 151 content->SetBounds(0, y, content_width, content_height);
166 } 152 }
167 153
168 gfx::Size EntryView::GetPreferredSize() const { 154 gfx::Size EntryView::GetPreferredSize() const {
169 DCHECK_EQ(1, child_count()); 155 DCHECK_EQ(1, child_count());
170 gfx::Size size = child_at(0)->GetPreferredSize(); 156 gfx::Size size = child_at(0)->GetPreferredSize();
171 size.SetToMax(gfx::Size(settings::kWidth, settings::kEntryHeight)); 157 size.SetToMax(gfx::Size(kWidth, settings::kEntryHeight));
172 return size; 158 return size;
173 } 159 }
174 160
175 void EntryView::GetAccessibleState(ui::AXViewState* state) { 161 void EntryView::GetAccessibleState(ui::AXViewState* state) {
176 DCHECK_EQ(1, child_count()); 162 DCHECK_EQ(1, child_count());
177 child_at(0)->GetAccessibleState(state); 163 child_at(0)->GetAccessibleState(state);
178 } 164 }
179 165
180 void EntryView::OnFocus() { 166 void EntryView::OnFocus() {
181 views::View::OnFocus(); 167 views::View::OnFocus();
(...skipping 14 matching lines...) Expand all
196 View::OnPaint(canvas); 182 View::OnPaint(canvas);
197 views::Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); 183 views::Painter::PaintFocusPainter(this, canvas, focus_painter_.get());
198 } 184 }
199 185
200 void EntryView::OnBlur() { 186 void EntryView::OnBlur() {
201 View::OnBlur(); 187 View::OnBlur();
202 // We render differently when focused. 188 // We render differently when focused.
203 SchedulePaint(); 189 SchedulePaint();
204 } 190 }
205 191
192 // NotifierGroupComboboxModel --------------------------------------------------
193
194 class NotifierGroupComboboxModel : public ui::ComboboxModel {
195 public:
196 explicit NotifierGroupComboboxModel(
197 NotifierSettingsProvider* notifier_settings_provider);
198 ~NotifierGroupComboboxModel() override;
199
200 // ui::ComboboxModel:
201 int GetItemCount() const override;
202 base::string16 GetItemAt(int index) override;
203
204 private:
205 NotifierSettingsProvider* notifier_settings_provider_;
206
207 DISALLOW_COPY_AND_ASSIGN(NotifierGroupComboboxModel);
208 };
209
210 NotifierGroupComboboxModel::NotifierGroupComboboxModel(
211 NotifierSettingsProvider* notifier_settings_provider)
212 : notifier_settings_provider_(notifier_settings_provider) {}
213
214 NotifierGroupComboboxModel::~NotifierGroupComboboxModel() {}
215
216 int NotifierGroupComboboxModel::GetItemCount() const {
217 return notifier_settings_provider_->GetNotifierGroupCount();
218 }
219
220 base::string16 NotifierGroupComboboxModel::GetItemAt(int index) {
221 const NotifierGroup& group =
222 notifier_settings_provider_->GetNotifierGroupAt(index);
223 return group.login_info.empty() ? group.name : group.login_info;
224 }
225
206 } // namespace 226 } // namespace
207 227
208
209 // NotifierGroupMenuModel -----------------------------------------------------
210
211 class NotifierGroupMenuModel : public ui::SimpleMenuModel,
212 public ui::SimpleMenuModel::Delegate {
213 public:
214 NotifierGroupMenuModel(NotifierSettingsProvider* notifier_settings_provider);
215 ~NotifierGroupMenuModel() override;
216
217 // ui::SimpleMenuModel::Delegate:
218 bool IsCommandIdChecked(int command_id) const override;
219 bool IsCommandIdEnabled(int command_id) const override;
220 void ExecuteCommand(int command_id, int event_flags) override;
221
222 private:
223 NotifierSettingsProvider* notifier_settings_provider_;
224
225 DISALLOW_COPY_AND_ASSIGN(NotifierGroupMenuModel);
226 };
227
228 NotifierGroupMenuModel::NotifierGroupMenuModel(
229 NotifierSettingsProvider* notifier_settings_provider)
230 : ui::SimpleMenuModel(this),
231 notifier_settings_provider_(notifier_settings_provider) {
232 if (!notifier_settings_provider_)
233 return;
234
235 size_t num_menu_items = notifier_settings_provider_->GetNotifierGroupCount();
236 for (size_t i = 0; i < num_menu_items; ++i) {
237 const NotifierGroup& group =
238 notifier_settings_provider_->GetNotifierGroupAt(i);
239
240 AddCheckItem(i, group.login_info.empty() ? group.name : group.login_info);
sky 2016/09/01 04:13:03 Isn't the check item different than what you get w
Evan Stade 2016/09/01 20:08:41 Normally multiple things can be checked, but in th
sky 2016/09/01 21:52:13 Should you at least change the selection to reflec
Evan Stade 2016/09/06 17:43:50 not sure what you mean, doesn't that happen automa
241 }
242 }
243
244 NotifierGroupMenuModel::~NotifierGroupMenuModel() {}
245
246 bool NotifierGroupMenuModel::IsCommandIdChecked(int command_id) const {
247 // If there's no provider, assume only one notifier group - the active one.
248 return !notifier_settings_provider_ ||
249 notifier_settings_provider_->IsNotifierGroupActiveAt(command_id);
250 }
251
252 bool NotifierGroupMenuModel::IsCommandIdEnabled(int command_id) const {
253 return true;
254 }
255
256 void NotifierGroupMenuModel::ExecuteCommand(int command_id, int event_flags) {
257 if (!notifier_settings_provider_)
258 return;
259
260 size_t notifier_group_index = static_cast<size_t>(command_id);
261 size_t num_notifier_groups =
262 notifier_settings_provider_->GetNotifierGroupCount();
263 if (notifier_group_index >= num_notifier_groups)
264 return;
265
266 notifier_settings_provider_->SwitchToNotifierGroup(notifier_group_index);
267 }
268
269
270 // NotifierSettingsView::NotifierButton --------------------------------------- 228 // NotifierSettingsView::NotifierButton ---------------------------------------
271 229
272 // We do not use views::Checkbox class directly because it doesn't support 230 // We do not use views::Checkbox class directly because it doesn't support
273 // showing 'icon'. 231 // showing 'icon'.
274 NotifierSettingsView::NotifierButton::NotifierButton( 232 NotifierSettingsView::NotifierButton::NotifierButton(
275 NotifierSettingsProvider* provider, 233 NotifierSettingsProvider* provider,
276 Notifier* notifier, 234 Notifier* notifier,
277 views::ButtonListener* listener) 235 views::ButtonListener* listener)
278 : views::CustomButton(listener), 236 : views::CustomButton(listener),
279 provider_(provider), 237 provider_(provider),
280 notifier_(notifier), 238 notifier_(notifier),
281 icon_view_(new views::ImageView()), 239 icon_view_(new views::ImageView()),
282 name_view_(new views::Label(notifier_->name)), 240 name_view_(new views::Label(notifier_->name)),
283 checkbox_(new views::Checkbox(base::string16())), 241 checkbox_(new views::Checkbox(base::string16())),
284 learn_more_(NULL) { 242 learn_more_(nullptr) {
285 DCHECK(provider); 243 DCHECK(provider);
286 DCHECK(notifier); 244 DCHECK(notifier);
287 245
288 // Since there may never be an icon (but that could change at a later time), 246 // Since there may never be an icon (but that could change at a later time),
289 // we own the icon view here. 247 // we own the icon view here.
290 icon_view_->set_owned_by_client(); 248 icon_view_->set_owned_by_client();
291 249
292 checkbox_->SetChecked(notifier_->enabled); 250 checkbox_->SetChecked(notifier_->enabled);
293 checkbox_->set_listener(this); 251 checkbox_->set_listener(this);
294 checkbox_->SetFocusBehavior(FocusBehavior::NEVER); 252 checkbox_->SetFocusBehavior(FocusBehavior::NEVER);
295 checkbox_->SetAccessibleName(notifier_->name); 253 checkbox_->SetAccessibleName(notifier_->name);
296 254
297 if (ShouldHaveLearnMoreButton()) { 255 if (ShouldHaveLearnMoreButton()) {
298 // Create a more-info button that will be right-aligned. 256 // Create a more-info button that will be right-aligned.
299 learn_more_ = new views::ImageButton(this); 257 learn_more_ = new views::ImageButton(this);
300 learn_more_->SetFocusPainter(CreateFocusPainter()); 258 learn_more_->SetFocusPainter(CreateFocusPainter());
301 learn_more_->SetFocusForPlatform(); 259 learn_more_->SetFocusForPlatform();
302 260
303 ui::ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 261 ui::ResourceBundle& rb = ResourceBundle::GetSharedInstance();
304 learn_more_->SetImage( 262 learn_more_->SetImage(
305 views::Button::STATE_NORMAL, 263 views::Button::STATE_NORMAL,
306 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS)); 264 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS));
307 learn_more_->SetImage( 265 learn_more_->SetImage(
308 views::Button::STATE_HOVERED, 266 views::Button::STATE_HOVERED,
309 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS_HOVER)); 267 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS_HOVER));
310 learn_more_->SetImage( 268 learn_more_->SetImage(
311 views::Button::STATE_PRESSED, 269 views::Button::STATE_PRESSED,
312 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS_PRESSED)); 270 rb.GetImageSkiaNamed(IDR_NOTIFICATION_ADVANCED_SETTINGS_PRESSED));
313 learn_more_->SetState(views::Button::STATE_NORMAL); 271 learn_more_->SetState(views::Button::STATE_NORMAL);
314 int learn_more_border_width = 272 int learn_more_border_width = (kLearnMoreTargetWidth - kLearnMoreSize) / 2;
315 (settings::kLearnMoreTargetWidth - settings::kLearnMoreSize) / 2;
316 int learn_more_border_height = 273 int learn_more_border_height =
317 (settings::kLearnMoreTargetHeight - settings::kLearnMoreSize) / 2; 274 (kLearnMoreTargetHeight - kLearnMoreSize) / 2;
318 // The image itself is quite small, this large invisible border creates a 275 // The image itself is quite small, this large invisible border creates a
319 // much bigger click target. 276 // much bigger click target.
320 learn_more_->SetBorder( 277 learn_more_->SetBorder(
321 views::Border::CreateEmptyBorder(learn_more_border_height, 278 views::Border::CreateEmptyBorder(learn_more_border_height,
322 learn_more_border_width, 279 learn_more_border_width,
323 learn_more_border_height, 280 learn_more_border_height,
324 learn_more_border_width)); 281 learn_more_border_width));
325 learn_more_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, 282 learn_more_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
326 views::ImageButton::ALIGN_MIDDLE); 283 views::ImageButton::ALIGN_MIDDLE);
327 } 284 }
(...skipping 21 matching lines...) Expand all
349 void NotifierSettingsView::NotifierButton::SetChecked(bool checked) { 306 void NotifierSettingsView::NotifierButton::SetChecked(bool checked) {
350 checkbox_->SetChecked(checked); 307 checkbox_->SetChecked(checked);
351 notifier_->enabled = checked; 308 notifier_->enabled = checked;
352 } 309 }
353 310
354 bool NotifierSettingsView::NotifierButton::checked() const { 311 bool NotifierSettingsView::NotifierButton::checked() const {
355 return checkbox_->checked(); 312 return checkbox_->checked();
356 } 313 }
357 314
358 bool NotifierSettingsView::NotifierButton::has_learn_more() const { 315 bool NotifierSettingsView::NotifierButton::has_learn_more() const {
359 return learn_more_ != NULL; 316 return learn_more_ != nullptr;
360 } 317 }
361 318
362 const Notifier& NotifierSettingsView::NotifierButton::notifier() const { 319 const Notifier& NotifierSettingsView::NotifierButton::notifier() const {
363 return *notifier_.get(); 320 return *notifier_.get();
364 } 321 }
365 322
366 void NotifierSettingsView::NotifierButton::SendLearnMorePressedForTest() { 323 void NotifierSettingsView::NotifierButton::SendLearnMorePressedForTest() {
367 if (learn_more_ == NULL) 324 if (learn_more_ == nullptr)
368 return; 325 return;
369 gfx::Point point(110, 120); 326 gfx::Point point(110, 120);
370 ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, point, point, 327 ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, point, point,
371 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 328 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
372 ui::EF_LEFT_MOUSE_BUTTON); 329 ui::EF_LEFT_MOUSE_BUTTON);
373 ButtonPressed(learn_more_, pressed); 330 ButtonPressed(learn_more_, pressed);
374 } 331 }
375 332
376 void NotifierSettingsView::NotifierButton::ButtonPressed( 333 void NotifierSettingsView::NotifierButton::ButtonPressed(
377 views::Button* button, 334 views::Button* button,
378 const ui::Event& event) { 335 const ui::Event& event) {
379 if (button == checkbox_) { 336 if (button == checkbox_) {
380 // The checkbox state has already changed at this point, but we'll update 337 // The checkbox state has already changed at this point, but we'll update
381 // the state on NotifierSettingsView::ButtonPressed() too, so here change 338 // the state on NotifierSettingsView::ButtonPressed() too, so here change
382 // back to the previous state. 339 // back to the previous state.
383 checkbox_->SetChecked(!checkbox_->checked()); 340 checkbox_->SetChecked(!checkbox_->checked());
384 CustomButton::NotifyClick(event); 341 CustomButton::NotifyClick(event);
385 } else if (button == learn_more_) { 342 } else if (button == learn_more_) {
386 DCHECK(provider_); 343 DCHECK(provider_);
387 provider_->OnNotifierAdvancedSettingsRequested(notifier_->notifier_id, 344 provider_->OnNotifierAdvancedSettingsRequested(notifier_->notifier_id,
388 NULL); 345 nullptr);
389 } 346 }
390 } 347 }
391 348
392 void NotifierSettingsView::NotifierButton::GetAccessibleState( 349 void NotifierSettingsView::NotifierButton::GetAccessibleState(
393 ui::AXViewState* state) { 350 ui::AXViewState* state) {
394 static_cast<views::View*>(checkbox_)->GetAccessibleState(state); 351 static_cast<views::View*>(checkbox_)->GetAccessibleState(state);
395 } 352 }
396 353
397 bool NotifierSettingsView::NotifierButton::ShouldHaveLearnMoreButton() const { 354 bool NotifierSettingsView::NotifierButton::ShouldHaveLearnMoreButton() const {
398 if (!provider_) 355 if (!provider_)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 if (has_learn_more) 409 if (has_learn_more)
453 layout->AddView(learn_more_); 410 layout->AddView(learn_more_);
454 411
455 Layout(); 412 Layout();
456 } 413 }
457 414
458 415
459 // NotifierSettingsView ------------------------------------------------------- 416 // NotifierSettingsView -------------------------------------------------------
460 417
461 NotifierSettingsView::NotifierSettingsView(NotifierSettingsProvider* provider) 418 NotifierSettingsView::NotifierSettingsView(NotifierSettingsProvider* provider)
462 : title_arrow_(NULL), 419 : title_arrow_(nullptr),
463 title_label_(NULL), 420 title_label_(nullptr),
464 notifier_group_selector_(NULL), 421 notifier_group_combobox_(nullptr),
465 scroller_(NULL), 422 scroller_(nullptr),
466 provider_(provider) { 423 provider_(provider) {
467 // |provider_| may be NULL in tests. 424 // |provider_| may be null in tests.
468 if (provider_) 425 if (provider_)
469 provider_->AddObserver(this); 426 provider_->AddObserver(this);
470 427
471 SetFocusBehavior(FocusBehavior::ALWAYS); 428 SetFocusBehavior(FocusBehavior::ALWAYS);
472 set_background( 429 set_background(
473 views::Background::CreateSolidBackground(kMessageCenterBackgroundColor)); 430 views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
474 SetPaintToLayer(true); 431 SetPaintToLayer(true);
475 432
476 title_label_ = new views::Label( 433 title_label_ = new views::Label(
477 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL), 434 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL),
478 ui::ResourceBundle::GetSharedInstance().GetFontList( 435 ui::ResourceBundle::GetSharedInstance().GetFontList(
479 ui::ResourceBundle::MediumFont)); 436 ui::ResourceBundle::MediumFont));
480 title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 437 title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
481 title_label_->SetMultiLine(true); 438 title_label_->SetMultiLine(true);
482 title_label_->SetBorder( 439 title_label_->SetBorder(
483 views::Border::CreateEmptyBorder(kComputedTitleTopMargin, 440 views::Border::CreateEmptyBorder(kComputedTitleTopMargin,
484 settings::kTitleMargin, 441 kTitleMargin,
485 kComputedTitleBottomMargin, 442 kComputedTitleBottomMargin,
486 settings::kTitleMargin)); 443 kTitleMargin));
487 444
488 AddChildView(title_label_); 445 AddChildView(title_label_);
489 446
490 scroller_ = new views::ScrollView(); 447 scroller_ = new views::ScrollView();
491 scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false)); 448 scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false));
492 AddChildView(scroller_); 449 AddChildView(scroller_);
493 450
494 std::vector<Notifier*> notifiers; 451 std::vector<Notifier*> notifiers;
495 if (provider_) 452 if (provider_)
496 provider_->GetNotifierList(&notifiers); 453 provider_->GetNotifierList(&notifiers);
497 454
498 UpdateContentsView(notifiers); 455 UpdateContentsView(notifiers);
499 } 456 }
500 457
501 NotifierSettingsView::~NotifierSettingsView() { 458 NotifierSettingsView::~NotifierSettingsView() {
502 // |provider_| may be NULL in tests. 459 // |provider_| may be null in tests.
503 if (provider_) 460 if (provider_)
504 provider_->RemoveObserver(this); 461 provider_->RemoveObserver(this);
505 } 462 }
506 463
507 bool NotifierSettingsView::IsScrollable() { 464 bool NotifierSettingsView::IsScrollable() {
508 return scroller_->height() < scroller_->contents()->height(); 465 return scroller_->height() < scroller_->contents()->height();
509 } 466 }
510 467
511 void NotifierSettingsView::UpdateIconImage(const NotifierId& notifier_id, 468 void NotifierSettingsView::UpdateIconImage(const NotifierId& notifier_id,
512 const gfx::Image& icon) { 469 const gfx::Image& icon) {
(...skipping 20 matching lines...) Expand all
533 490
534 void NotifierSettingsView::UpdateContentsView( 491 void NotifierSettingsView::UpdateContentsView(
535 const std::vector<Notifier*>& notifiers) { 492 const std::vector<Notifier*>& notifiers) {
536 buttons_.clear(); 493 buttons_.clear();
537 494
538 views::View* contents_view = new views::View(); 495 views::View* contents_view = new views::View();
539 contents_view->SetLayoutManager(new views::BoxLayout( 496 contents_view->SetLayoutManager(new views::BoxLayout(
540 views::BoxLayout::kVertical, settings::kHorizontalMargin, 0, 0)); 497 views::BoxLayout::kVertical, settings::kHorizontalMargin, 0, 0));
541 498
542 views::View* contents_title_view = new views::View(); 499 views::View* contents_title_view = new views::View();
543 contents_title_view->SetLayoutManager( 500 contents_title_view->SetLayoutManager(new views::BoxLayout(
544 new views::BoxLayout(views::BoxLayout::kVertical, 501 views::BoxLayout::kVertical, 0, 0, kComputedTitleElementSpacing));
545 kComputedContentsTitleMargin,
546 0,
547 kComputedTitleElementSpacing));
548 502
549 bool need_account_switcher = 503 bool need_account_switcher =
550 provider_ && provider_->GetNotifierGroupCount() > 1; 504 provider_ && provider_->GetNotifierGroupCount() > 1;
551 int top_label_resource_id = 505 int top_label_resource_id =
552 need_account_switcher ? IDS_MESSAGE_CENTER_SETTINGS_DESCRIPTION_MULTIUSER 506 need_account_switcher ? IDS_MESSAGE_CENTER_SETTINGS_DESCRIPTION_MULTIUSER
553 : IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION; 507 : IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION;
554 508
555 views::Label* top_label = 509 views::Label* top_label =
556 new views::Label(l10n_util::GetStringUTF16(top_label_resource_id)); 510 new views::Label(l10n_util::GetStringUTF16(top_label_resource_id));
557 511 top_label->SetBorder(views::Border::CreateEmptyBorder(
512 gfx::Insets(0, kTitleMargin - settings::kHorizontalMargin)));
558 top_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 513 top_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
559 top_label->SetMultiLine(true); 514 top_label->SetMultiLine(true);
560 top_label->SetBorder(views::Border::CreateEmptyBorder( 515
561 0,
562 settings::kTitleMargin + kMenuButtonInnateMargin,
563 0,
564 settings::kTitleMargin + kMenuButtonInnateMargin));
565 contents_title_view->AddChildView(top_label); 516 contents_title_view->AddChildView(top_label);
566 517
567 if (need_account_switcher) { 518 if (need_account_switcher) {
568 const NotifierGroup& active_group = provider_->GetActiveNotifierGroup(); 519 const NotifierGroup& active_group = provider_->GetActiveNotifierGroup();
569 base::string16 notifier_group_text = active_group.login_info.empty() ? 520 base::string16 notifier_group_text = active_group.login_info.empty() ?
570 active_group.name : active_group.login_info; 521 active_group.name : active_group.login_info;
571 notifier_group_selector_ = 522 notifier_group_model_.reset(new NotifierGroupComboboxModel(provider_));
572 new views::MenuButton(notifier_group_text, this, true); 523 notifier_group_combobox_ = new views::Combobox(notifier_group_model_.get());
573 notifier_group_selector_->SetBorder(std::unique_ptr<views::Border>( 524 notifier_group_combobox_->set_listener(this);
574 new views::LabelButtonAssetBorder(views::Button::STYLE_BUTTON))); 525
575 notifier_group_selector_->SetFocusPainter(nullptr); 526 // Move the combobox over enough to align with the checkboxes.
576 notifier_group_selector_->set_animate_on_state_change(false); 527 views::View* combobox_spacer = new views::View();
577 notifier_group_selector_->SetFocusForPlatform(); 528 combobox_spacer->SetLayoutManager(new views::FillLayout());
578 notifier_group_selector_->set_request_focus_on_press(true); 529 int padding = views::LabelButtonAssetBorder::GetDefaultInsetsForStyle(
579 contents_title_view->AddChildView(notifier_group_selector_); 530 views::LabelButton::STYLE_TEXTBUTTON)
531 .left() -
532 notifier_group_combobox_->border()->GetInsets().left();
533 combobox_spacer->SetBorder(
534 views::Border::CreateEmptyBorder(0, padding, 0, 0));
535 combobox_spacer->AddChildView(notifier_group_combobox_);
536
537 contents_title_view->AddChildView(combobox_spacer);
580 } 538 }
581 539
582 contents_view->AddChildView(contents_title_view); 540 contents_view->AddChildView(contents_title_view);
583 541
584 size_t notifier_count = notifiers.size(); 542 size_t notifier_count = notifiers.size();
585 for (size_t i = 0; i < notifier_count; ++i) { 543 for (size_t i = 0; i < notifier_count; ++i) {
586 NotifierButton* button = new NotifierButton(provider_, notifiers[i], this); 544 NotifierButton* button = new NotifierButton(provider_, notifiers[i], this);
587 EntryView* entry = new EntryView(button); 545 EntryView* entry = new EntryView(button);
588 546
589 // This code emulates separators using borders. We will create an invisible 547 // This code emulates separators using borders. We will create an invisible
(...skipping 17 matching lines...) Expand all
607 } 565 }
608 566
609 scroller_->SetContents(contents_view); 567 scroller_->SetContents(contents_view);
610 568
611 contents_view->SetBoundsRect(gfx::Rect(contents_view->GetPreferredSize())); 569 contents_view->SetBoundsRect(gfx::Rect(contents_view->GetPreferredSize()));
612 InvalidateLayout(); 570 InvalidateLayout();
613 } 571 }
614 572
615 void NotifierSettingsView::Layout() { 573 void NotifierSettingsView::Layout() {
616 int title_height = title_label_->GetHeightForWidth(width()); 574 int title_height = title_label_->GetHeightForWidth(width());
617 title_label_->SetBounds(settings::kTitleMargin, 575 title_label_->SetBounds(0, 0, width(), title_height);
618 0,
619 width() - settings::kTitleMargin * 2,
620 title_height);
621 576
622 views::View* contents_view = scroller_->contents(); 577 views::View* contents_view = scroller_->contents();
623 int content_width = width(); 578 int content_width = width();
624 int content_height = contents_view->GetHeightForWidth(content_width); 579 int content_height = contents_view->GetHeightForWidth(content_width);
625 if (title_height + content_height > height()) { 580 if (title_height + content_height > height()) {
626 content_width -= scroller_->GetScrollBarWidth(); 581 content_width -= scroller_->GetScrollBarWidth();
627 content_height = contents_view->GetHeightForWidth(content_width); 582 content_height = contents_view->GetHeightForWidth(content_width);
628 } 583 }
629 contents_view->SetBounds(0, 0, content_width, content_height); 584 contents_view->SetBounds(0, 0, content_width, content_height);
630 scroller_->SetBounds(0, title_height, width(), height() - title_height); 585 scroller_->SetBounds(0, title_height, width(), height() - title_height);
631 } 586 }
632 587
633 gfx::Size NotifierSettingsView::GetMinimumSize() const { 588 gfx::Size NotifierSettingsView::GetMinimumSize() const {
634 gfx::Size size(settings::kWidth, settings::kMinimumHeight); 589 gfx::Size size(kWidth, kMinimumHeight);
635 int total_height = title_label_->GetPreferredSize().height() + 590 int total_height = title_label_->GetPreferredSize().height() +
636 scroller_->contents()->GetPreferredSize().height(); 591 scroller_->contents()->GetPreferredSize().height();
637 if (total_height > settings::kMinimumHeight) 592 if (total_height > kMinimumHeight)
638 size.Enlarge(scroller_->GetScrollBarWidth(), 0); 593 size.Enlarge(scroller_->GetScrollBarWidth(), 0);
639 return size; 594 return size;
640 } 595 }
641 596
642 gfx::Size NotifierSettingsView::GetPreferredSize() const { 597 gfx::Size NotifierSettingsView::GetPreferredSize() const {
643 gfx::Size preferred_size; 598 gfx::Size preferred_size;
644 gfx::Size title_size = title_label_->GetPreferredSize(); 599 gfx::Size title_size = title_label_->GetPreferredSize();
645 gfx::Size content_size = scroller_->contents()->GetPreferredSize(); 600 gfx::Size content_size = scroller_->contents()->GetPreferredSize();
646 return gfx::Size(std::max(title_size.width(), content_size.width()), 601 return gfx::Size(std::max(title_size.width(), content_size.width()),
647 title_size.height() + content_size.height()); 602 title_size.height() + content_size.height());
(...skipping 24 matching lines...) Expand all
672 buttons_.find(static_cast<NotifierButton*>(sender)); 627 buttons_.find(static_cast<NotifierButton*>(sender));
673 628
674 if (iter == buttons_.end()) 629 if (iter == buttons_.end())
675 return; 630 return;
676 631
677 (*iter)->SetChecked(!(*iter)->checked()); 632 (*iter)->SetChecked(!(*iter)->checked());
678 if (provider_) 633 if (provider_)
679 provider_->SetNotifierEnabled((*iter)->notifier(), (*iter)->checked()); 634 provider_->SetNotifierEnabled((*iter)->notifier(), (*iter)->checked());
680 } 635 }
681 636
682 void NotifierSettingsView::OnMenuButtonClicked(views::MenuButton* source, 637 void NotifierSettingsView::OnPerformAction(views::Combobox* combobox) {
683 const gfx::Point& point, 638 provider_->SwitchToNotifierGroup(combobox->selected_index());
684 const ui::Event* event) {
685 notifier_group_menu_model_.reset(new NotifierGroupMenuModel(provider_));
686 notifier_group_menu_runner_.reset(new views::MenuRunner(
687 notifier_group_menu_model_.get(), views::MenuRunner::CONTEXT_MENU));
688 gfx::Rect menu_anchor = source->GetBoundsInScreen();
689 menu_anchor.Inset(
690 gfx::Insets(0, kMenuWhitespaceOffset, 0, kMenuWhitespaceOffset));
691 if (views::MenuRunner::MENU_DELETED ==
692 notifier_group_menu_runner_->RunMenuAt(GetWidget(),
693 notifier_group_selector_,
694 menu_anchor,
695 views::MENU_ANCHOR_BUBBLE_ABOVE,
696 ui::MENU_SOURCE_MOUSE))
697 return;
698 MessageCenterView* center_view = static_cast<MessageCenterView*>(parent()); 639 MessageCenterView* center_view = static_cast<MessageCenterView*>(parent());
699 center_view->OnSettingsChanged(); 640 center_view->OnSettingsChanged();
700 } 641 }
701 642
702 } // namespace message_center 643 } // namespace message_center
OLDNEW
« ui/base/models/combobox_model.h ('K') | « ui/message_center/views/notifier_settings_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698