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