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 3 // found in the LICENSE file. 4 5 #include "ui/views/controls/button/checkbox.h" 6 7 #include "grit/ui_resources.h" 8 #include "ui/base/accessibility/accessible_view_state.h" 9 #include "ui/base/resource/resource_bundle.h" 10 #include "ui/views/controls/button/label_button_border.h" 11 #include "ui/views/painter.h" 12 13 namespace views { 14 15 // static 16 const char Checkbox::kViewClassName[] = "Checkbox"; 17 18 Checkbox::Checkbox(const string16& label) 19 : LabelButton(NULL, label), 20 checked_(false) { 21 SetHorizontalAlignment(gfx::ALIGN_LEFT); 22 LabelButtonBorder* button_border = static_cast<LabelButtonBorder*>(border()); 23 button_border->SetPainter(false, STATE_HOVERED, NULL); 24 button_border->SetPainter(false, STATE_PRESSED, NULL); 25 // Inset the trailing side by a couple pixels for the focus border. 26 button_border->set_insets(gfx::Insets(0, 0, 0, 2)); 27 SetFocusable(true); 28 29 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 30 31 // Unchecked/Unfocused images. 32 SetCustomImage(false, false, STATE_NORMAL, 33 *rb.GetImageSkiaNamed(IDR_CHECKBOX)); 34 SetCustomImage(false, false, STATE_HOVERED, 35 *rb.GetImageSkiaNamed(IDR_CHECKBOX_HOVER)); 36 SetCustomImage(false, false, STATE_PRESSED, 37 *rb.GetImageSkiaNamed(IDR_CHECKBOX_PRESSED)); 38 SetCustomImage(false, false, STATE_DISABLED, 39 *rb.GetImageSkiaNamed(IDR_CHECKBOX_DISABLED)); 40 41 // Checked/Unfocused images. 42 SetCustomImage(true, false, STATE_NORMAL, 43 *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED)); 44 SetCustomImage(true, false, STATE_HOVERED, 45 *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_HOVER)); 46 SetCustomImage(true, false, STATE_PRESSED, 47 *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_PRESSED)); 48 SetCustomImage(true, false, STATE_DISABLED, 49 *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_DISABLED)); 50 51 // Unchecked/Focused images. 52 SetCustomImage(false, true, STATE_NORMAL, 53 *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED)); 54 SetCustomImage(false, true, STATE_HOVERED, 55 *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_HOVER)); 56 SetCustomImage(false, true, STATE_PRESSED, 57 *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_PRESSED)); 58 59 // Checked/Focused images. 60 SetCustomImage(true, true, STATE_NORMAL, 61 *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED)); 62 SetCustomImage(true, true, STATE_HOVERED, 63 *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED_HOVER)); 64 SetCustomImage(true, true, STATE_PRESSED, 65 *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED_PRESSED)); 66 67 // Limit the checkbox height to match the legacy appearance. 68 const gfx::Size preferred_size(LabelButton::GetPreferredSize()); 69 set_min_size(gfx::Size(0, preferred_size.height() + 4)); 70 } 71 72 Checkbox::~Checkbox() { 73 } 74 75 void Checkbox::SetChecked(bool checked) { 76 checked_ = checked; 77 UpdateImage(); 78 } 79 80 void Checkbox::Layout() { 81 LabelButton::Layout(); 82 83 // Construct a focus painter that only surrounds the label area. 84 gfx::Rect rect = label()->GetMirroredBounds(); 85 rect.Inset(-2, 3); 86 SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( 87 gfx::Insets(rect.y(), rect.x(), 88 height() - rect.bottom(), 89 width() - rect.right()))); 90 } 91 92 const char* Checkbox::GetClassName() const { 93 return kViewClassName; 94 } 95 96 void Checkbox::GetAccessibleState(ui::AccessibleViewState* state) { 97 LabelButton::GetAccessibleState(state); 98 state->role = ui::AccessibilityTypes::ROLE_CHECKBUTTON; 99 state->state = checked() ? ui::AccessibilityTypes::STATE_CHECKED : 0; 100 } 101 102 void Checkbox::OnFocus() { 103 LabelButton::OnFocus(); 104 UpdateImage(); 105 } 106 107 void Checkbox::OnBlur() { 108 LabelButton::OnBlur(); 109 UpdateImage(); 110 } 111 112 const gfx::ImageSkia& Checkbox::GetImage(ButtonState for_state) { 113 const size_t checked_index = checked_ ? 1 : 0; 114 const size_t focused_index = HasFocus() ? 1 : 0; 115 if (for_state != STATE_NORMAL && 116 images_[checked_index][focused_index][for_state].isNull()) 117 return images_[checked_index][focused_index][STATE_NORMAL]; 118 return images_[checked_index][focused_index][for_state]; 119 } 120 121 void Checkbox::SetCustomImage(bool checked, 122 bool focused, 123 ButtonState for_state, 124 const gfx::ImageSkia& image) { 125 const size_t checked_index = checked ? 1 : 0; 126 const size_t focused_index = focused ? 1 : 0; 127 images_[checked_index][focused_index][for_state] = image; 128 UpdateImage(); 129 } 130 131 void Checkbox::NotifyClick(const ui::Event& event) { 132 SetChecked(!checked()); 133 LabelButton::NotifyClick(event); 134 } 135 136 ui::NativeTheme::Part Checkbox::GetThemePart() const { 137 return ui::NativeTheme::kCheckbox; 138 } 139 140 void Checkbox::GetExtraParams(ui::NativeTheme::ExtraParams* params) const { 141 LabelButton::GetExtraParams(params); 142 params->button.checked = checked_; 143 } 144 145 } // namespace views 146