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

Side by Side Diff: ui/views/controls/combobox/combobox.cc

Issue 141523005: Combobox: Rename styles to STYLE_NORMAL and STYLE_ACTION and modify behaviors (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sky's review Created 6 years, 10 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/views/controls/combobox/combobox.h ('k') | ui/views/controls/combobox/combobox_unittest.cc » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/combobox/combobox.h" 5 #include "ui/views/controls/combobox/combobox.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "grit/ui_resources.h" 9 #include "grit/ui_resources.h"
10 #include "ui/base/accessibility/accessible_view_state.h" 10 #include "ui/base/accessibility/accessible_view_state.h"
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 } // namespace 212 } // namespace
213 213
214 // static 214 // static
215 const char Combobox::kViewClassName[] = "views/Combobox"; 215 const char Combobox::kViewClassName[] = "views/Combobox";
216 216
217 //////////////////////////////////////////////////////////////////////////////// 217 ////////////////////////////////////////////////////////////////////////////////
218 // Combobox, public: 218 // Combobox, public:
219 219
220 Combobox::Combobox(ui::ComboboxModel* model) 220 Combobox::Combobox(ui::ComboboxModel* model)
221 : model_(model), 221 : model_(model),
222 style_(STYLE_SHOW_DROP_DOWN_ON_CLICK), 222 style_(STYLE_NORMAL),
223 listener_(NULL), 223 listener_(NULL),
224 selected_index_(model_->GetDefaultIndex()), 224 selected_index_(model_->GetDefaultIndex()),
225 invalid_(false), 225 invalid_(false),
226 disclosure_arrow_(ui::ResourceBundle::GetSharedInstance().GetImageNamed( 226 disclosure_arrow_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
227 IDR_MENU_DROPARROW).ToImageSkia()), 227 IDR_MENU_DROPARROW).ToImageSkia()),
228 dropdown_open_(false), 228 dropdown_open_(false),
229 text_button_(new TransparentButton(this)), 229 text_button_(new TransparentButton(this)),
230 arrow_button_(new TransparentButton(this)) { 230 arrow_button_(new TransparentButton(this)) {
231 model_->AddObserver(this); 231 model_->AddObserver(this);
232 UpdateFromModel(); 232 UpdateFromModel();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 const gfx::FontList& Combobox::GetFontList() { 269 const gfx::FontList& Combobox::GetFontList() {
270 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 270 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
271 return rb.GetFontList(ui::ResourceBundle::BaseFont); 271 return rb.GetFontList(ui::ResourceBundle::BaseFont);
272 } 272 }
273 273
274 void Combobox::SetStyle(Style style) { 274 void Combobox::SetStyle(Style style) {
275 if (style_ == style) 275 if (style_ == style)
276 return; 276 return;
277 277
278 style_ = style; 278 style_ = style;
279 if (style_ == STYLE_ACTION)
280 selected_index_ = 0;
279 281
280 UpdateBorder(); 282 UpdateBorder();
283 UpdateFromModel();
281 PreferredSizeChanged(); 284 PreferredSizeChanged();
282 } 285 }
283 286
284 void Combobox::ModelChanged() { 287 void Combobox::ModelChanged() {
285 selected_index_ = std::min(0, model_->GetItemCount()); 288 selected_index_ = std::min(0, model_->GetItemCount());
286 UpdateFromModel(); 289 UpdateFromModel();
287 PreferredSizeChanged(); 290 PreferredSizeChanged();
288 } 291 }
289 292
290 void Combobox::SetSelectedIndex(int index) { 293 void Combobox::SetSelectedIndex(int index) {
294 if (style_ == STYLE_ACTION)
295 return;
296
291 selected_index_ = index; 297 selected_index_ = index;
292 SchedulePaint(); 298 SchedulePaint();
293 } 299 }
294 300
295 bool Combobox::SelectValue(const base::string16& value) { 301 bool Combobox::SelectValue(const base::string16& value) {
302 if (style_ == STYLE_ACTION)
303 return false;
304
296 for (int i = 0; i < model()->GetItemCount(); ++i) { 305 for (int i = 0; i < model()->GetItemCount(); ++i) {
297 if (value == model()->GetItemAt(i)) { 306 if (value == model()->GetItemAt(i)) {
298 SetSelectedIndex(i); 307 SetSelectedIndex(i);
299 return true; 308 return true;
300 } 309 }
301 } 310 }
302 return false; 311 return false;
303 } 312 }
304 313
305 void Combobox::SetAccessibleName(const base::string16& name) { 314 void Combobox::SetAccessibleName(const base::string16& name) {
(...skipping 17 matching lines...) Expand all
323 } 332 }
324 333
325 void Combobox::Layout() { 334 void Combobox::Layout() {
326 PrefixDelegate::Layout(); 335 PrefixDelegate::Layout();
327 336
328 gfx::Insets insets = GetInsets(); 337 gfx::Insets insets = GetInsets();
329 int text_button_width = 0; 338 int text_button_width = 0;
330 int arrow_button_width = 0; 339 int arrow_button_width = 0;
331 340
332 switch (style_) { 341 switch (style_) {
333 case STYLE_SHOW_DROP_DOWN_ON_CLICK: { 342 case STYLE_NORMAL: {
334 arrow_button_width = width(); 343 arrow_button_width = width();
335 break; 344 break;
336 } 345 }
337 case STYLE_NOTIFY_ON_CLICK: { 346 case STYLE_ACTION: {
338 arrow_button_width = GetDisclosureArrowLeftPadding() + 347 arrow_button_width = GetDisclosureArrowLeftPadding() +
339 disclosure_arrow_->width() + GetDisclosureArrowRightPadding(); 348 disclosure_arrow_->width() + GetDisclosureArrowRightPadding();
340 text_button_width = width() - arrow_button_width; 349 text_button_width = width() - arrow_button_width;
341 break; 350 break;
342 } 351 }
343 } 352 }
344 353
345 int arrow_button_x = std::max(0, text_button_width); 354 int arrow_button_x = std::max(0, text_button_width);
346 text_button_->SetBounds(0, 0, std::max(0, text_button_width), height()); 355 text_button_->SetBounds(0, 0, std::max(0, text_button_width), height());
347 arrow_button_->SetBounds(arrow_button_x, 0, arrow_button_width, height()); 356 arrow_button_->SetBounds(arrow_button_x, 0, arrow_button_width, height());
348 } 357 }
349 358
350 bool Combobox::IsItemChecked(int id) const { 359 bool Combobox::IsItemChecked(int id) const {
351 return false; 360 return false;
352 } 361 }
353 362
354 bool Combobox::IsCommandEnabled(int id) const { 363 bool Combobox::IsCommandEnabled(int id) const {
355 return model()->IsItemEnabledAt(MenuCommandToIndex(id)); 364 return model()->IsItemEnabledAt(MenuCommandToIndex(id));
356 } 365 }
357 366
358 void Combobox::ExecuteCommand(int id) { 367 void Combobox::ExecuteCommand(int id) {
359 selected_index_ = MenuCommandToIndex(id); 368 selected_index_ = MenuCommandToIndex(id);
360 OnSelectionChanged(); 369 OnSelectionChanged();
370 if (style_ == STYLE_ACTION)
sky 2014/01/28 14:57:14 Isn't the selectionchanged enough here? By that I
hajimehoshi 2014/01/29 05:28:38 How about pressing enter or space key? In this cas
sky 2014/01/29 17:16:56 If the menu is open and you press space/enter Sele
hajimehoshi 2014/01/29 21:32:30 I mean that if the action combobox is focused and
371 HandleClickEvent();
361 } 372 }
362 373
363 bool Combobox::GetAccelerator(int id, ui::Accelerator* accel) { 374 bool Combobox::GetAccelerator(int id, ui::Accelerator* accel) {
364 return false; 375 return false;
365 } 376 }
366 377
367 int Combobox::GetRowCount() { 378 int Combobox::GetRowCount() {
368 return model()->GetItemCount(); 379 return model()->GetItemCount();
369 } 380 }
370 381
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 new_index = GetAdjacentIndex(model(), 1, -1); 460 new_index = GetAdjacentIndex(model(), 1, -1);
450 break; 461 break;
451 462
452 // Move to the previous item if any. 463 // Move to the previous item if any.
453 case ui::VKEY_UP: 464 case ui::VKEY_UP:
454 new_index = GetAdjacentIndex(model(), -1, selected_index_); 465 new_index = GetAdjacentIndex(model(), -1, selected_index_);
455 break; 466 break;
456 467
457 // Click the button only when the button style mode. 468 // Click the button only when the button style mode.
458 case ui::VKEY_SPACE: 469 case ui::VKEY_SPACE:
459 if (style_ == STYLE_NOTIFY_ON_CLICK) { 470 if (style_ == STYLE_ACTION) {
460 // When pressing space, the click event will be raised after the key is 471 // When pressing space, the click event will be raised after the key is
461 // released. 472 // released.
462 text_button_->SetState(Button::STATE_PRESSED); 473 text_button_->SetState(Button::STATE_PRESSED);
463 } else { 474 } else {
464 return false; 475 return false;
465 } 476 }
466 break; 477 break;
467 478
468 // Click the button only when the button style mode. 479 // Click the button only when the button style mode.
469 case ui::VKEY_RETURN: 480 case ui::VKEY_RETURN:
470 if (style_ != STYLE_NOTIFY_ON_CLICK) 481 if (style_ != STYLE_ACTION)
471 return false; 482 return false;
472 HandleClickEvent(); 483 HandleClickEvent();
473 break; 484 break;
474 485
475 default: 486 default:
476 return false; 487 return false;
477 } 488 }
478 489
479 if (show_menu) { 490 if (show_menu) {
480 UpdateFromModel(); 491 UpdateFromModel();
481 ShowDropDownMenu(ui::MENU_SOURCE_KEYBOARD); 492 ShowDropDownMenu(ui::MENU_SOURCE_KEYBOARD);
482 } else if (new_index != selected_index_ && new_index != kNoSelection) { 493 } else if (new_index != selected_index_ && new_index != kNoSelection) {
483 DCHECK(!model()->IsItemSeparatorAt(new_index)); 494 if (style_ != STYLE_ACTION) {
484 selected_index_ = new_index; 495 DCHECK(!model()->IsItemSeparatorAt(new_index));
485 OnSelectionChanged(); 496 selected_index_ = new_index;
497 OnSelectionChanged();
498 }
486 } 499 }
487 500
488 return true; 501 return true;
489 } 502 }
490 503
491 bool Combobox::OnKeyReleased(const ui::KeyEvent& e) { 504 bool Combobox::OnKeyReleased(const ui::KeyEvent& e) {
492 if (style_ != STYLE_NOTIFY_ON_CLICK) 505 if (style_ != STYLE_ACTION)
493 return false; // crbug.com/127520 506 return false; // crbug.com/127520
494 507
495 if (e.key_code() == ui::VKEY_SPACE) 508 if (e.key_code() == ui::VKEY_SPACE && style_ == STYLE_ACTION)
496 HandleClickEvent(); 509 HandleClickEvent();
497 510
498 return false; 511 return false;
499 } 512 }
500 513
501 void Combobox::OnPaint(gfx::Canvas* canvas) { 514 void Combobox::OnPaint(gfx::Canvas* canvas) {
502 switch (style_) { 515 switch (style_) {
503 case STYLE_SHOW_DROP_DOWN_ON_CLICK: { 516 case STYLE_NORMAL: {
504 OnPaintBackground(canvas); 517 OnPaintBackground(canvas);
505 PaintText(canvas); 518 PaintText(canvas);
506 OnPaintBorder(canvas); 519 OnPaintBorder(canvas);
507 break; 520 break;
508 } 521 }
509 case STYLE_NOTIFY_ON_CLICK: { 522 case STYLE_ACTION: {
510 PaintButtons(canvas); 523 PaintButtons(canvas);
511 PaintText(canvas); 524 PaintText(canvas);
512 break; 525 break;
513 } 526 }
514 } 527 }
515 } 528 }
516 529
517 void Combobox::OnFocus() { 530 void Combobox::OnFocus() {
518 GetInputMethod()->OnFocus(); 531 GetInputMethod()->OnFocus();
519 View::OnFocus(); 532 View::OnFocus();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE; 571 ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE;
559 if (event.IsKeyEvent()) 572 if (event.IsKeyEvent())
560 source_type = ui::MENU_SOURCE_KEYBOARD; 573 source_type = ui::MENU_SOURCE_KEYBOARD;
561 else if (event.IsGestureEvent() || event.IsTouchEvent()) 574 else if (event.IsGestureEvent() || event.IsTouchEvent())
562 source_type = ui::MENU_SOURCE_TOUCH; 575 source_type = ui::MENU_SOURCE_TOUCH;
563 ShowDropDownMenu(source_type); 576 ShowDropDownMenu(source_type);
564 } 577 }
565 } 578 }
566 579
567 void Combobox::UpdateFromModel() { 580 void Combobox::UpdateFromModel() {
568 int max_width = 0;
569 const gfx::FontList& font_list = Combobox::GetFontList(); 581 const gfx::FontList& font_list = Combobox::GetFontList();
570 582
571 MenuItemView* menu = new MenuItemView(this); 583 MenuItemView* menu = new MenuItemView(this);
572 // MenuRunner owns |menu|. 584 // MenuRunner owns |menu|.
573 dropdown_list_menu_runner_.reset(new MenuRunner(menu)); 585 dropdown_list_menu_runner_.reset(new MenuRunner(menu));
574 586
575 int num_items = model()->GetItemCount(); 587 int num_items = model()->GetItemCount();
588 int width = 0;
576 for (int i = 0; i < num_items; ++i) { 589 for (int i = 0; i < num_items; ++i) {
577 if (model()->IsItemSeparatorAt(i)) { 590 if (model()->IsItemSeparatorAt(i)) {
578 menu->AppendSeparator(); 591 menu->AppendSeparator();
579 continue; 592 continue;
580 } 593 }
581 594
582 base::string16 text = model()->GetItemAt(i); 595 base::string16 text = model()->GetItemAt(i);
583 596
584 // Inserting the Unicode formatting characters if necessary so that the 597 // Inserting the Unicode formatting characters if necessary so that the
585 // text is displayed correctly in right-to-left UIs. 598 // text is displayed correctly in right-to-left UIs.
586 base::i18n::AdjustStringForLocaleDirection(&text); 599 base::i18n::AdjustStringForLocaleDirection(&text);
587 600
588 menu->AppendMenuItem(i + kFirstMenuItemId, text, MenuItemView::NORMAL); 601 menu->AppendMenuItem(i + kFirstMenuItemId, text, MenuItemView::NORMAL);
589 max_width = std::max(max_width, gfx::GetStringWidth(text, font_list)); 602
603 if (style_ != STYLE_ACTION || i == selected_index_)
604 width = std::max(width, gfx::GetStringWidth(text, font_list));
590 } 605 }
591 606
592 content_size_.SetSize(max_width, font_list.GetHeight()); 607 content_size_.SetSize(width, font_list.GetHeight());
593 } 608 }
594 609
595 void Combobox::UpdateBorder() { 610 void Combobox::UpdateBorder() {
596 scoped_ptr<FocusableBorder> border(new FocusableBorder()); 611 scoped_ptr<FocusableBorder> border(new FocusableBorder());
597 if (style_ == STYLE_NOTIFY_ON_CLICK) 612 if (style_ == STYLE_ACTION)
598 border->SetInsets(8, 13, 8, 13); 613 border->SetInsets(8, 13, 8, 13);
599 if (invalid_) 614 if (invalid_)
600 border->SetColor(kWarningColor); 615 border->SetColor(kWarningColor);
601 SetBorder(border.PassAs<Border>()); 616 SetBorder(border.PassAs<Border>());
602 } 617 }
603 618
604 void Combobox::AdjustBoundsForRTLUI(gfx::Rect* rect) const { 619 void Combobox::AdjustBoundsForRTLUI(gfx::Rect* rect) const {
605 rect->set_x(GetMirroredXForRect(*rect)); 620 rect->set_x(GetMirroredXForRect(*rect));
606 } 621 }
607 622
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 gfx::Rect arrow_bounds(arrow_x, 654 gfx::Rect arrow_bounds(arrow_x,
640 height() / 2 - disclosure_arrow_->height() / 2, 655 height() / 2 - disclosure_arrow_->height() / 2,
641 disclosure_arrow_->width(), 656 disclosure_arrow_->width(),
642 disclosure_arrow_->height()); 657 disclosure_arrow_->height());
643 AdjustBoundsForRTLUI(&arrow_bounds); 658 AdjustBoundsForRTLUI(&arrow_bounds);
644 659
645 canvas->DrawImageInt(*disclosure_arrow_, arrow_bounds.x(), arrow_bounds.y()); 660 canvas->DrawImageInt(*disclosure_arrow_, arrow_bounds.x(), arrow_bounds.y());
646 } 661 }
647 662
648 void Combobox::PaintButtons(gfx::Canvas* canvas) { 663 void Combobox::PaintButtons(gfx::Canvas* canvas) {
649 DCHECK(style_ == STYLE_NOTIFY_ON_CLICK); 664 DCHECK(style_ == STYLE_ACTION);
650 665
651 gfx::ScopedCanvas scoped_canvas(canvas); 666 gfx::ScopedCanvas scoped_canvas(canvas);
652 if (base::i18n::IsRTL()) { 667 if (base::i18n::IsRTL()) {
653 canvas->Translate(gfx::Vector2d(width(), 0)); 668 canvas->Translate(gfx::Vector2d(width(), 0));
654 canvas->Scale(-1, 1); 669 canvas->Scale(-1, 1);
655 } 670 }
656 671
657 bool focused = HasFocus(); 672 bool focused = HasFocus();
658 const std::vector<const gfx::ImageSkia*>& arrow_button_images = 673 const std::vector<const gfx::ImageSkia*>& arrow_button_images =
659 menu_button_images_[focused][ 674 menu_button_images_[focused][
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 int Combobox::MenuCommandToIndex(int menu_command_id) const { 776 int Combobox::MenuCommandToIndex(int menu_command_id) const {
762 // (note that the id received is offset by kFirstMenuItemId) 777 // (note that the id received is offset by kFirstMenuItemId)
763 // Revert menu ID offset to map back to combobox model. 778 // Revert menu ID offset to map back to combobox model.
764 int index = menu_command_id - kFirstMenuItemId; 779 int index = menu_command_id - kFirstMenuItemId;
765 DCHECK_LT(index, model()->GetItemCount()); 780 DCHECK_LT(index, model()->GetItemCount());
766 return index; 781 return index;
767 } 782 }
768 783
769 int Combobox::GetDisclosureArrowLeftPadding() const { 784 int Combobox::GetDisclosureArrowLeftPadding() const {
770 switch (style_) { 785 switch (style_) {
771 case STYLE_SHOW_DROP_DOWN_ON_CLICK: 786 case STYLE_NORMAL:
772 return kDisclosureArrowLeftPadding; 787 return kDisclosureArrowLeftPadding;
773 case STYLE_NOTIFY_ON_CLICK: 788 case STYLE_ACTION:
774 return kDisclosureArrowButtonLeftPadding; 789 return kDisclosureArrowButtonLeftPadding;
775 } 790 }
776 NOTREACHED(); 791 NOTREACHED();
777 return 0; 792 return 0;
778 } 793 }
779 794
780 int Combobox::GetDisclosureArrowRightPadding() const { 795 int Combobox::GetDisclosureArrowRightPadding() const {
781 switch (style_) { 796 switch (style_) {
782 case STYLE_SHOW_DROP_DOWN_ON_CLICK: 797 case STYLE_NORMAL:
783 return kDisclosureArrowRightPadding; 798 return kDisclosureArrowRightPadding;
784 case STYLE_NOTIFY_ON_CLICK: 799 case STYLE_ACTION:
785 return kDisclosureArrowButtonRightPadding; 800 return kDisclosureArrowButtonRightPadding;
786 } 801 }
787 NOTREACHED(); 802 NOTREACHED();
788 return 0; 803 return 0;
789 } 804 }
790 805
791 void Combobox::HandleClickEvent() { 806 void Combobox::HandleClickEvent() {
792 if (style_ != STYLE_NOTIFY_ON_CLICK) 807 if (style_ != STYLE_ACTION)
793 return; 808 return;
794 809
795 if (listener_) 810 if (listener_)
796 listener_->OnComboboxTextButtonClicked(this); 811 listener_->OnComboboxTextButtonClicked(this);
812
813 selected_index_ = 0;
sky 2014/01/28 14:57:14 Same worry about the possibility of this being del
797 } 814 }
798 815
799 } // namespace views 816 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/combobox/combobox.h ('k') | ui/views/controls/combobox/combobox_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698