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