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

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

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