15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/checkbox.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/resources/grit/ui_resources.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/controls/button/label_button_border.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/painter.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char Checkbox::kViewClassName[] = "Checkbox"; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Checkbox::Checkbox(const base::string16& label) 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : LabelButton(NULL, label), 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checked_(false) { 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetHorizontalAlignment(gfx::ALIGN_LEFT); 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<LabelButtonBorder> button_border(new LabelButtonBorder(style())); 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) button_border->SetPainter(false, STATE_HOVERED, NULL); 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) button_border->SetPainter(false, STATE_PRESSED, NULL); 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Inset the trailing side by a couple pixels for the focus border. 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) button_border->set_insets(gfx::Insets(0, 0, 0, 2)); 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBorder(button_border.PassAs<Border>()); 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetFocusable(true); 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Unchecked/Unfocused images. 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(false, false, STATE_NORMAL, 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX)); 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(false, false, STATE_HOVERED, 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_HOVER)); 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(false, false, STATE_PRESSED, 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_PRESSED)); 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(false, false, STATE_DISABLED, 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_DISABLED)); 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Checked/Unfocused images. 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(true, false, STATE_NORMAL, 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED)); 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(true, false, STATE_HOVERED, 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_HOVER)); 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(true, false, STATE_PRESSED, 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_PRESSED)); 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(true, false, STATE_DISABLED, 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_CHECKED_DISABLED)); 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Unchecked/Focused images. 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(false, true, STATE_NORMAL, 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED)); 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(false, true, STATE_HOVERED, 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_HOVER)); 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(false, true, STATE_PRESSED, 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_PRESSED)); 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Checked/Focused images. 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(true, true, STATE_NORMAL, 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED)); 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(true, true, STATE_HOVERED, 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED_HOVER)); 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetCustomImage(true, true, STATE_PRESSED, 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *rb.GetImageSkiaNamed(IDR_CHECKBOX_FOCUSED_CHECKED_PRESSED)); 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Limit the checkbox height to match the legacy appearance. 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const gfx::Size preferred_size(LabelButton::GetPreferredSize()); 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetMinSize(gfx::Size(0, preferred_size.height() + 4)); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Checkbox::~Checkbox() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Checkbox::SetChecked(bool checked) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checked_ = checked; 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateImage(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Checkbox::Layout() { 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LabelButton::Layout(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Construct a focus painter that only surrounds the label area. 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gfx::Rect rect = label()->GetMirroredBounds(); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rect.Inset(-2, 3); 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Insets(rect.y(), rect.x(), 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) height() - rect.bottom(), 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) width() - rect.right()))); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* Checkbox::GetClassName() const { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void Checkbox::GetAccessibleState(ui::AXViewState* state) { 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LabelButton::GetAccessibleState(state); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->role = ui::AX_ROLE_CHECK_BOX; 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (checked()) 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch state->AddStateFlag(ui::AX_STATE_CHECKED); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Checkbox::OnFocus() { 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LabelButton::OnFocus(); 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateImage(); 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Checkbox::OnBlur() { 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LabelButton::OnBlur(); 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateImage(); 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const gfx::ImageSkia& Checkbox::GetImage(ButtonState for_state) { 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t checked_index = checked_ ? 1 : 0; 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t focused_index = HasFocus() ? 1 : 0; 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (for_state != STATE_NORMAL && 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) images_[checked_index][focused_index][for_state].isNull()) 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return images_[checked_index][focused_index][STATE_NORMAL]; 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return images_[checked_index][focused_index][for_state]; 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Checkbox::SetCustomImage(bool checked, 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool focused, 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ButtonState for_state, 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const gfx::ImageSkia& image) { 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t checked_index = checked ? 1 : 0; 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t focused_index = focused ? 1 : 0; 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) images_[checked_index][focused_index][for_state] = image; 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateImage(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Checkbox::NotifyClick(const ui::Event& event) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetChecked(!checked()); 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LabelButton::NotifyClick(event); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::NativeTheme::Part Checkbox::GetThemePart() const { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NativeTheme::kCheckbox; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Checkbox::GetExtraParams(ui::NativeTheme::ExtraParams* params) const { 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LabelButton::GetExtraParams(params); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->button.checked = checked_; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace views 148