Home | History | Annotate | Download | only in button
      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 
     12 namespace views {
     13 
     14 // static
     15 const char Checkbox::kViewClassName[] = "Checkbox";
     16 
     17 Checkbox::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 
     71 Checkbox::~Checkbox() {
     72 }
     73 
     74 void Checkbox::SetChecked(bool checked) {
     75   checked_ = checked;
     76   UpdateImage();
     77 }
     78 
     79 void 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 
     89 const char* Checkbox::GetClassName() const {
     90   return kViewClassName;
     91 }
     92 
     93 void 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 
     99 void Checkbox::OnFocus() {
    100   UpdateImage();
    101 }
    102 
    103 void Checkbox::OnBlur() {
    104   UpdateImage();
    105 }
    106 
    107 const 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 
    116 void 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 
    126 void Checkbox::NotifyClick(const ui::Event& event) {
    127   SetChecked(!checked());
    128   LabelButton::NotifyClick(event);
    129 }
    130 
    131 ui::NativeTheme::Part Checkbox::GetThemePart() const {
    132   return ui::NativeTheme::kCheckbox;
    133 }
    134 
    135 void Checkbox::GetExtraParams(ui::NativeTheme::ExtraParams* params) const {
    136   LabelButton::GetExtraParams(params);
    137   params->button.checked = checked_;
    138 }
    139 
    140 }  // namespace views
    141