Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 size_to_largest_label_(style_ == STYLE_NORMAL), | 399 size_to_largest_label_(style_ == STYLE_NORMAL), |
| 400 weak_ptr_factory_(this) { | 400 weak_ptr_factory_(this) { |
| 401 ModelChanged(); | 401 ModelChanged(); |
| 402 #if defined(OS_MACOSX) | 402 #if defined(OS_MACOSX) |
| 403 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); | 403 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); |
| 404 #else | 404 #else |
| 405 SetFocusBehavior(FocusBehavior::ALWAYS); | 405 SetFocusBehavior(FocusBehavior::ALWAYS); |
| 406 #endif | 406 #endif |
| 407 | 407 |
| 408 UpdateBorder(); | 408 UpdateBorder(); |
| 409 arrow_image_ = PlatformStyle::CreateComboboxArrow(enabled(), style); | |
| 410 // set_background() takes ownership but takes a raw pointer. | 409 // set_background() takes ownership but takes a raw pointer. |
| 411 std::unique_ptr<Background> b = | 410 std::unique_ptr<Background> b = |
| 412 PlatformStyle::CreateComboboxBackground(GetArrowContainerWidth()); | 411 PlatformStyle::CreateComboboxBackground(GetArrowContainerWidth()); |
| 413 set_background(b.release()); | 412 set_background(b.release()); |
| 414 | 413 |
| 415 // Initialize the button images. | 414 // Initialize the button images. |
| 416 Button::ButtonState button_states[] = { | 415 Button::ButtonState button_states[] = { |
| 417 Button::STATE_DISABLED, | 416 Button::STATE_DISABLED, |
| 418 Button::STATE_NORMAL, | 417 Button::STATE_NORMAL, |
| 419 Button::STATE_HOVERED, | 418 Button::STATE_HOVERED, |
| 420 Button::STATE_PRESSED, | 419 Button::STATE_PRESSED, |
| 421 }; | 420 }; |
| 422 for (int i = 0; i < 2; i++) { | 421 for (int i = 0; i < 2; i++) { |
| 423 for (size_t state_index = 0; state_index < arraysize(button_states); | 422 for (size_t state_index = 0; state_index < arraysize(button_states); |
| 424 state_index++) { | 423 state_index++) { |
| 425 Button::ButtonState state = button_states[state_index]; | 424 Button::ButtonState state = button_states[state_index]; |
| 426 size_t num; | 425 size_t num; |
| 427 bool focused = !!i; | 426 bool focused = !!i; |
| 428 const int* ids = GetBodyButtonImageIds(focused, state, &num); | 427 const int* ids = GetBodyButtonImageIds(focused, state, &num); |
| 429 body_button_painters_[focused][state].reset( | 428 body_button_painters_[focused][state].reset( |
| 430 Painter::CreateImageGridPainter(ids)); | 429 Painter::CreateImageGridPainter(ids)); |
| 431 menu_button_images_[focused][state] = GetMenuButtonImages(focused, state); | 430 menu_button_images_[focused][state] = GetMenuButtonImages(focused, state); |
| 432 } | 431 } |
| 433 } | 432 } |
| 434 | 433 |
| 435 text_button_->SetVisible(true); | 434 text_button_->SetVisible(true); |
| 436 arrow_button_->SetVisible(true); | 435 arrow_button_->SetVisible(true); |
| 437 AddChildView(text_button_); | 436 AddChildView(text_button_); |
| 438 AddChildView(arrow_button_); | 437 AddChildView(arrow_button_); |
| 438 | |
| 439 // A layer is applied to make sure that canvas bounds are snapped to pixel | |
|
sky
2016/09/06 23:20:41
ugh!
| |
| 440 // boundaries (for the sake of drawing the arrow). | |
| 441 if (UseMd()) { | |
| 442 SetPaintToLayer(true); | |
| 443 layer()->SetFillsBoundsOpaquely(false); | |
| 444 } else { | |
| 445 arrow_image_ = PlatformStyle::CreateComboboxArrow(enabled(), style); | |
| 446 } | |
| 439 } | 447 } |
| 440 | 448 |
| 441 Combobox::~Combobox() { | 449 Combobox::~Combobox() { |
| 442 if (GetInputMethod() && selector_.get()) { | 450 if (GetInputMethod() && selector_.get()) { |
| 443 // Combobox should have been blurred before destroy. | 451 // Combobox should have been blurred before destroy. |
| 444 DCHECK(selector_.get() != GetInputMethod()->GetTextInputClient()); | 452 DCHECK(selector_.get() != GetInputMethod()->GetTextInputClient()); |
| 445 } | 453 } |
| 446 } | 454 } |
| 447 | 455 |
| 448 // static | 456 // static |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 gfx::Rect text_bounds(x, y, text_width, text_height); | 789 gfx::Rect text_bounds(x, y, text_width, text_height); |
| 782 AdjustBoundsForRTLUI(&text_bounds); | 790 AdjustBoundsForRTLUI(&text_bounds); |
| 783 canvas->DrawStringRect(text, font_list, text_color, text_bounds); | 791 canvas->DrawStringRect(text, font_list, text_color, text_bounds); |
| 784 | 792 |
| 785 gfx::Rect arrow_bounds(disclosure_arrow_offset, 0, GetArrowContainerWidth(), | 793 gfx::Rect arrow_bounds(disclosure_arrow_offset, 0, GetArrowContainerWidth(), |
| 786 height()); | 794 height()); |
| 787 arrow_bounds = | 795 arrow_bounds = |
| 788 PositionArrowWithinContainer(arrow_bounds, ArrowSize(), style_); | 796 PositionArrowWithinContainer(arrow_bounds, ArrowSize(), style_); |
| 789 AdjustBoundsForRTLUI(&arrow_bounds); | 797 AdjustBoundsForRTLUI(&arrow_bounds); |
| 790 | 798 |
| 791 canvas->DrawImageInt(arrow_image_, arrow_bounds.x(), arrow_bounds.y()); | 799 if (UseMd()) { |
| 800 // Since this is a core piece of UI and vector icons don't handle fractional | |
| 801 // scale factors particularly well, manually draw an arrow and make sure it | |
| 802 // looks good at all scale factors. | |
| 803 float dsf = canvas->UndoDeviceScaleFactor(); | |
| 804 SkScalar x = std::ceil(arrow_bounds.x() * dsf); | |
| 805 SkScalar y = std::ceil(arrow_bounds.y() * dsf); | |
| 806 SkScalar height = std::floor(arrow_bounds.height() * dsf); | |
| 807 SkPath path; | |
| 808 // This epsilon makes sure that all the aliasing pixels are slightly more | |
| 809 // than half full. Otherwise, rounding issues cause some to be considered | |
| 810 // slightly less than half full and come out a little lighter. | |
| 811 const SkScalar kEpsilon = 0.0001f; | |
| 812 path.moveTo(x - kEpsilon, y); | |
| 813 path.rLineTo(height, height); | |
| 814 path.rLineTo(2 * kEpsilon, 0); | |
| 815 path.rLineTo(height, -height); | |
| 816 path.close(); | |
| 817 SkPaint paint; | |
| 818 paint.setColor(GetNativeTheme()->GetSystemColor( | |
| 819 ui::NativeTheme::kColorId_ButtonEnabledColor)); | |
| 820 paint.setAntiAlias(true); | |
| 821 canvas->DrawPath(path, paint); | |
| 822 } else { | |
| 823 canvas->DrawImageInt(arrow_image_, arrow_bounds.x(), arrow_bounds.y()); | |
| 824 } | |
| 792 } | 825 } |
| 793 | 826 |
| 794 void Combobox::PaintButtons(gfx::Canvas* canvas) { | 827 void Combobox::PaintButtons(gfx::Canvas* canvas) { |
| 795 DCHECK(style_ == STYLE_ACTION); | 828 DCHECK(style_ == STYLE_ACTION); |
| 796 | 829 |
| 797 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width()); | 830 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width()); |
| 798 | 831 |
| 799 bool focused = HasFocus(); | 832 bool focused = HasFocus(); |
| 800 const std::vector<const gfx::ImageSkia*>& arrow_button_images = | 833 const std::vector<const gfx::ImageSkia*>& arrow_button_images = |
| 801 menu_button_images_[focused][ | 834 menu_button_images_[focused][ |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 902 // This combobox may be deleted by the listener. | 935 // This combobox may be deleted by the listener. |
| 903 base::WeakPtr<Combobox> weak_ptr = weak_ptr_factory_.GetWeakPtr(); | 936 base::WeakPtr<Combobox> weak_ptr = weak_ptr_factory_.GetWeakPtr(); |
| 904 if (listener_) | 937 if (listener_) |
| 905 listener_->OnPerformAction(this); | 938 listener_->OnPerformAction(this); |
| 906 | 939 |
| 907 if (weak_ptr && style_ == STYLE_ACTION) | 940 if (weak_ptr && style_ == STYLE_ACTION) |
| 908 selected_index_ = 0; | 941 selected_index_ = 0; |
| 909 } | 942 } |
| 910 | 943 |
| 911 gfx::Size Combobox::ArrowSize() const { | 944 gfx::Size Combobox::ArrowSize() const { |
| 912 return arrow_image_.size(); | 945 return UseMd() ? gfx::Size(8, 4) : arrow_image_.size(); |
| 913 } | 946 } |
| 914 | 947 |
| 915 gfx::Size Combobox::GetContentSize() const { | 948 gfx::Size Combobox::GetContentSize() const { |
| 916 const gfx::FontList& font_list = GetFontList(); | 949 const gfx::FontList& font_list = GetFontList(); |
| 917 | 950 |
| 918 int width = 0; | 951 int width = 0; |
| 919 for (int i = 0; i < model()->GetItemCount(); ++i) { | 952 for (int i = 0; i < model()->GetItemCount(); ++i) { |
| 920 if (model_->IsItemSeparatorAt(i)) | 953 if (model_->IsItemSeparatorAt(i)) |
| 921 continue; | 954 continue; |
| 922 | 955 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 935 } | 968 } |
| 936 | 969 |
| 937 int Combobox::GetArrowContainerWidth() const { | 970 int Combobox::GetArrowContainerWidth() const { |
| 938 int padding = style_ == STYLE_NORMAL | 971 int padding = style_ == STYLE_NORMAL |
| 939 ? PlatformStyle::kComboboxNormalArrowPadding * 2 | 972 ? PlatformStyle::kComboboxNormalArrowPadding * 2 |
| 940 : kActionLeftPadding + kActionRightPadding; | 973 : kActionLeftPadding + kActionRightPadding; |
| 941 return ArrowSize().width() + padding; | 974 return ArrowSize().width() + padding; |
| 942 } | 975 } |
| 943 | 976 |
| 944 } // namespace views | 977 } // namespace views |
| OLD | NEW |